温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

基于C语言如何实现的流水跑马灯

发布时间:2020-10-16 15:20:40 来源:亿速云 阅读:326 作者:小新 栏目:编程语言

这篇文章给大家分享的是有关基于C语言如何实现的流水跑马灯的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。

1.题目:

跑马灯

(1)基本要求

采用8254精确定时,LED的点亮规律为LED8-LED1,每一个LED的点亮时间间隔由逻辑电平开关K1、K2与K3选择。K1的时间间隔为0.5S,K2的时间间隔为1.0S,K3的时间间隔为1.5S。当主机键盘按下任意键时停止演示。

(2)设计提示

采用8255的A口接LED灯,B口接逻辑电平开关K1、K2与K3。在8254的中断服务程序中完成对灯的控制,主程序检测开关的变化,改变点亮LED灯的时间间隔。

(3)进一步设计要求

LED的点亮规律变为LED8-LED1-LED8


2.分析:

基本原理设计

步骤一:8255采用B口工作在方式0,进行输入,获取开关(注:为了便于进行课设操作,我们采用了K2,K1,K0以此来取代K3,K2,K1,实现的要求完全一致)K2K1K0的值,这里会有三个值,分别是二进制编码的100,010,001,即十进制的4,2,1,分别对应LED灯点亮的时间间隔1.5s,1.0s,0.5s。


步骤二:8254采用工作方式三,产生一个固定频率的方波,去不断触发中断服务程序。在主程序中,获取8255的B口输入值,根据输入值给8254的计数器1写入对应的初始值,在OUT1端就能得到一个固定频率的方波信号,这里我们连接了一个K7所对应的灯,以此来进行验证方波的产生以及通过灯闪烁的频率可以大致判断方波的频率,来对应时间间隔1.5s,1.0s,0.5s。


步骤三:8254产生的方波信号输出,连接到中断接口IR10,用来利用方波信号的频率按照一定的时间间隔来出发中断服务程序。

步骤四:中断服务程序按照8254的方波频率,在一定的时间间隔内被加载执行。在中断服务程序中实现对8255的A口输出的改变,来控制LED7-LED0的闪烁变化,即实现跑马灯。


3.代码实现:

//******************************************************************************************************************
/*
实验接线:
	8254:
		片选信号CS接Y0;GATE0、GATE1级联接+5V;CLK0接1MHz;CLK1接OUT0;
		OUT1接k5(进行8254的方波显示);
	8255:
		片选信号CS接Y1;A口作为输出用排线接LED灯;PB0、PB1、PB2作为输入分别接K0、K1、K2;
	中断:
		IR10接OUT1(中断控制程序控制LED灯的闪烁变化);
*/
//******************************************************************************************************************
//8255模块的设置
void  init(void);//初始化
void	ISR(void);
int i=0,j=0;
const unsigned short
Port8255Base = 0x288;  
const unsigned char
    ControlWord8255 = 0x82;
void init8255(void);// 8255初始化
//******************************************************************************************************************
//关于8254模块的设置
//通道0: 控制字00110110 -> 36H,即0x36,CLK0=1MHz,OUT0=0.01s,初值=F(clk)*T(out) 初始值:COUNT0=10000
//通道1: 控制字01110110 -> 76H,即0x76,CLK1=OUT0,初值=T1(out)/T1(clk)
//当OUT1=0.5s,k3=0,k2=0,k0=1,1 初始值:COUNT1=50
//当OUT1=1.0s,k3=0,k2=1,k0=0,2 初始值:COUNT1=100
//当OUT1=1.5s,k3=1,k2=0,k0=0,4 初始值:COUNT1=150
void	init8254(void);// 8254初始化
const unsigned short
Port8254Base = 0x280,   //计数器1端口地址为p8254Base+1,端口地址为p8254Base+3.
counter0=10000;
const unsigned char
ControlWord8254ch0 = 0x36, ControlWord8254ch2 = 0x76;
unsigned short  
	counter1=100;//计数器初值
byte   pData; 
unsigned char pdata=0x80;
bool flag=true;
//******************************************************************************************************************

//主函数
void main()
{  
      init();
	  init8254();// 8254初始化
	  init8255();//8255初始化
	  printf("\n start...\n");
	  while (!_kbhit())
	  {
			PortReadByte(Port8255Base + 1, &pData);	
			
			//写入计数器1的初始值
			if(pData==1){
				//k0为1的情况,k2k1k0=001,即时间间隔为0.5秒
				counter1=50;
				PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
				PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
				printf("=switch state:%x  LED灯点亮间隔0.5秒=\n",pData);	
			}
			if(pData==2){
				//k1为1的情况,k2k1k0=010,即时间间隔为1.0秒
				counter1=100;
				PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
				PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
				printf("=switch state:%x  LED灯点亮间隔1.0秒=\n",pData);	

			}
			if(pData==4){
				//k2为1的情况,k2k1k0=100,即时间间隔为1.5秒
				counter1=150;
				PortWriteByte(Port8254Base+1 , counter1%256); // 写计数器1计数初值低8位
				PortWriteByte(Port8254Base+1 , counter1/256); // 写计数器1计数初值高8位
				printf("=switch state:%x  LED灯点亮间隔1.5秒=\n",pData);	
	     }		 
		  sleep(3000);// delay 1s

		  EnableIntr(); // 开中断,功能等效于汇编语言指令sti
		  RegisterLocalISREx(ISR,10); // 加载中断服务程
		  printf("Wait for the switch state change...\n\n");
          }
	  _getch();
	   printf("\n Press any key over...\n");
       //DisableIntr(); // 开中断,功能等效于汇编语言指令cli
	   Cleanup();
}

//中断服务程序,实现跑马灯的流水
void	ISR(void)
 {
     if(flag)
	 {
		_asm
		{
			 ror  pdata,1  //循环右移指令		 
		}
	 }
	 else
	 {
		_asm
		{
			rol  pdata,1  //循环左移指令
		}
	 }
	j++;
	if(j==7)
	{
		flag = false;
	}
	if(j==14){
		flag = true;
		j=0;
	}
	 PortWriteByte(Port8255Base,pdata);
 }

//机箱的初始化
void  init(void)
{
     if(!Startup())	// 加载实验平台I/O驱动程序		
	   {
		  printf("\n\n        ERROR: Open Device Error!请打开实验箱电源\n");
		   _getch();
		  exit(0); // return to Windows
	   }
  }

//8254初始化
void	init8254(void)
 {
	PortWriteByte(Port8254Base + 3, ControlWord8254ch0); // 写计数器0控制字
	PortWriteByte(Port8254Base + 3, ControlWord8254ch2); // 写计数器1控制字
	PortWriteByte(Port8254Base , counter0%256); // 写计数器0计数初值低8位
	PortWriteByte(Port8254Base , counter0/256); // 写计数器0计数初值高8位
 }

//8255初始化
void	init8255(void)
{
    PortWriteByte(Port8255Base + 3, ControlWord8255); // 写8255控制字  
	PortWriteByte(Port8255Base,pdata);
}

感谢各位的阅读!关于基于C语言如何实现的流水跑马灯就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI