C语言笔记-基于C语言实现的流水跑马灯

今天,偶忽然想起大二时学跑马灯,当时一个个敲代码最后运行出来跑马灯的状态,我现在都还记得,把代码运行到实体上最后呈现的效果真是令人愉悦,话不多说,下面我将就跑马灯制作流程给大家分享一下。

1.题目:

跑马灯

(1)基本要求

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

(2)设计提示

立即学习“C语言免费学习笔记(深入)”;

采用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);//初始化voidISR(void);int i=0,j=0;const unsigned shortPort8255Base = 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=150voidinit8254(void);// 8254初始化const unsigned shortPort8254Base = 0x280,   //计数器1端口地址为p8254Base+1,端口地址为p8254Base+3.counter0=10000;const unsigned charControlWord8254ch0 = 0x36, ControlWord8254ch1 = 0x76;unsigned short  counter1=100;//计数器初值byte   pData; unsigned char pdata=0x80;bool flag=true;//******************************************************************************************************************//主函数void main(){        init();  init8254();// 8254初始化  init8255();//8255初始化  printf(" start...");  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秒=",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秒=",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秒=",pData);     }   sleep(3000);// delay 1s  EnableIntr(); // 开中断,功能等效于汇编语言指令sti  RegisterLocalISREx(ISR,10); // 加载中断服务程  printf("Wait for the switch state change...");          }  _getch();   printf(" Press any key over...");       //DisableIntr(); // 开中断,功能等效于汇编语言指令cli   Cleanup();}//中断服务程序,实现跑马灯的流水voidISR(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("        ERROR: Open Device Error!请打开实验箱电源");   _getch();  exit(0); // return to Windows   }  }//8254初始化voidinit8254(void) {PortWriteByte(Port8254Base + 3, ControlWord8254ch0); // 写计数器0控制字PortWriteByte(Port8254Base + 3, ControlWord8254ch1); // 写计数器1控制字PortWriteByte(Port8254Base , counter0%256); // 写计数器0计数初值低8位PortWriteByte(Port8254Base , counter0/256); // 写计数器0计数初值高8位 }//8255初始化voidinit8255(void){    PortWriteByte(Port8255Base + 3, ControlWord8255); // 写8255控制字  PortWriteByte(Port8255Base,pdata);}

登录后复制

【推荐课程:C视频教程】

以上就是C语言笔记-基于C语言实现的流水跑马灯的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2492833.html

(0)
上一篇 2025年3月5日 01:18:34
下一篇 2025年3月5日 01:18:49

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • C++中动态内存分配与命名空间介绍

    本篇文章给大家带来的内容是介绍c++++中的动态内存分配与命名空间,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 1、C++中的动态内存分配  ● 通过new关键字进行动态内存申请  ● C++中的动态内存申请时基于类型进…

    编程技术 2025年3月5日
    100
  • c++ 图解层序遍历和逐层打印智能指针建造的二叉树

    二叉树是极为常见的数据结构,关于如何遍历其中元素的文章更是数不胜数。然而大多数文章都是讲解的前序/中序/后序遍历,有关逐层打印元素的文章并不多,已有文章的讲解也较为晦涩读起来不得要领。本文将用形象的图片加上清晰的代码帮助你理解层序遍历的实现…

    2025年3月5日 编程技术
    200
  • c++如何读取excel

    c++如何读取excel?c++ odbc操作excel全过程 推荐:《c++教程》 想要通过ODBC直接读、写Excel表格文件,首先,应确保ODBC中已安装有Excel表格文件的驱动”MICROSOFT EXCEL DRIV…

    2025年3月5日
    200
  • C语言比较三个数大小

    C语言比较三个数大小 首先比较第一个数和第二个数的大小,如果第一个数大于第二个数,则将第一个数和第二个数互换,不大于则不作处理;然后将第二个数和第三个数比较,同样,若大于则将它们互换;最后比较完以后,最后一个数就是最大的。 代码 立即学习“…

    2025年3月5日
    200
  • c语言break和continue用法

    c语言break和continue用法 break用于跳出switch结构,如果在循环语句中,break语句是用于直接跳出循环,而continue语句与break语句不同,在循环体内遇到该语句时,将跳过本次循环并开始下一轮循环。 示例 使用…

    2025年3月5日
    200
  • C语言 strchr 函数用法

    C语言 strchr 函数用法 C语言中strchr函数作用是为在一个串中查找给定字符的第一个匹配之处,该函的原型为“char *strchr(const char *str, int c)”,使用时向str传入要被检索的字符串,c传入要搜…

    2025年3月5日
    200
  • C语言中fputc函数的用法

    C语言中fputc函数的用法 C语言中fputc函数的用法为“int fgetc (FILE *fp)”,该函数的作用是从指定的文件中读取一个字符, 读取成功时会返回读取到的字符,读取到文件末尾或读取失败时返回EOF。 推荐教程:《C语言》…

    2025年3月5日
    200
  • C语言中for用法是什么?

    C语言中for用法是: for 循环语句的一般形式为: for (表达式1; 表达式2; 表达式3){        语句;} 登录后复制 首先要强调两点: 1) 表达式1、表达式2和表达式3之间是用分号;隔开的,千万不要写成逗号。 立即学…

    2025年3月5日
    200
  • C++语言标识符的命名规则是什么?

    C++语言标识符的命名规则是:1、标识符的命名要以字母大小写或者下划线【_】开头;2、尽量将标识符命名为有意义的单词等,增加程序的可读性;3、尽量在一个变量的命名中将不同单词的首字母大写。 C++语言标识符的命名规则是: 标识符是一个字符序…

    2025年3月5日
    200
  • c语言三目运算符怎么用?

    c语言三目运算符的用法:首先对于条件表达式【b ? x : y】,计算条件b;然后进行判断,如果b的值为true,计算x的值,运算结果为x的值,否则,计算y的值,运算结果为y的值即可。 C语言三目运算符用法: 对于条件表达式b ? x : …

    2025年3月5日
    200

发表回复

登录后才能评论