#include <iom16v.h> #include <macros.h> unsigned int time1,time2,all_time=1,stop=0,i=0,flag=1; unsigned char num[]={0x7e,0x30,0x5b,0x7b,0x3d,0x6d,0x5f,0x77,0x4f,0x79}; unsigned int a=1; unsigned int aw=0; void port_init(void) { DDRB = (1<<PB4) | (1<<PB5) | (1<<PB7); PORTD|=0xFF; DDRB=0xF0; PORTB=0xF0; } void init_devices(void) { CLI(); UCSRB=0x00; UCSRC=0x86; UBRRL=25; UBRRH=0x00; UCSRB=0x98; SEI(); } void init_max7219(void) { send_max7219(0x0c,0x01); send_max7219(0x0f,0x00); send_max7219(0x09,0x0f); send_max7219(0x0b,0x03); send_max7219(0x0a,0x04); } void send_max7219(unsigned char address,unsigned char data) { PORTB&=~(1<<PB4); SPI_MasterTransmit(address); SPI_MasterTransmit(data); PORTB|=(1<<PB4); } void SPI_MasterTransmit(unsigned char cData) { unsigned char tmp; PORTB&=(1<<PB7); tmp=SPSR; SPDR=cData; while(!(SPSR&(1<<SPIF))); } #pragma interrupt_handler timer1_compa_isr:20 void timer1_compa_isr(void) { i++; if(i%200==0) { a++; } if(a==9999) { a=0; } } #pragma interrupt_handler ext_int1_isr:3 void ext_int1_isr(void) { switch (aw) { case 0: TCCR0=0b00001000; aw=1; break; case 1: TCCR0=0b00001101; aw=0; break; } } void main(void) { unsigned int b,c,d,e; port_init(); SPCR=(1<<MSTR)|(1<<SPE)|(1<<SPR0); init_devices(); init_max7219(); TCCR0=0b00001000; OCR0=0b00000100; TIMSK=0b00000010; MCUCR=0x0A; GICR|=0xC0; send_max7219(1,0); send_max7219(2,0); send_max7219(3,0); send_max7219(4,0); TCCR0=0b00001101; while (1) { if(i%200==0) { send_max7219(4,e=a/1000); send_max7219(3,d=((a-e*1000)/100)); send_max7219(2,c=((a-e*1000-d*100)/10)); send_max7219(1,b=a%10); } } }每行代码的作用
时间: 2023-11-18 17:02:57 浏览: 201
矩阵键盘--4接口
这是一个基于 AVR 微控制器的程序,实现了使用 MAX7219 控制芯片驱动 7 段数码管显示计时器,并且通过外部中断按钮控制计时器的开始和停止。下面是每行代码的作用:
1. `#include <iom16v.h>`:包含 AVR 微控制器头文件。
2. `#include <macros.h>`:包含宏定义的头文件。
3. `unsigned int time1,time2,all_time=1,stop=0,i=0,flag=1;`:定义多个 unsigned int 类型的变量,用于计时和控制。
4. `unsigned char num[]={0x7e,0x30,0x5b,0x7b,0x3d,0x6d,0x5f,0x77,0x4f,0x79};`:定义一个数组 num,存储 0-9 的 7 段数码管编码。
5. `unsigned int a=1;`:初始化计时器初始值为 1。
6. `unsigned int aw=0;`:定义 aw 变量,用于在外部中断中切换计时器的开始和停止。
7. `void port_init(void)`:初始化端口。
8. `DDRB = (1<<PB4) | (1<<PB5) | (1<<PB7);`:设置 PB4、PB5、PB7 为输出模式。
9. `PORTD|=0xFF;`:将 PD0-PD7 设为上拉输入模式。
10. `DDRB=0xF0;`:设置 PB0-PB3 为输入模式,PB4-PB7 为输出模式。
11. `PORTB=0xF0;`:将 PB0-PB3 设为上拉输入模式。
12. `void init_devices(void)`:初始化设备。
13. `CLI();`:关闭全局中断。
14. `UCSRB=0x00;`:禁用 USART 。
15. `UCSRC=0x86;`:设置 USART 控制寄存器,8 位数据,1 位停止位,无奇偶校验。
16. `UBRRL=25;`:设置波特率为 9600。
17. `UBRRH=0x00;`:设置波特率为 9600。
18. `UCSRB=0x98;`:使能 USART 的接收和发送。
19. `SEI();`:开启全局中断。
20. `void init_max7219(void)`:初始化 MAX7219 控制芯片。
21. `send_max7219(0x0c,0x01);`:设置显示模式为正常显示。
22. `send_max7219(0x0f,0x00);`:设置显示亮度为最低。
23. `send_max7219(0x09,0x0f);`:设置扫描限制为所有位。
24. `send_max7219(0x0b,0x03);`:设置扫描方式为静态扫描。
25. `send_max7219(0x0a,0x04);`:设置扫描速度为最快。
26. `void send_max7219(unsigned char address,unsigned char data)`:发送数据到 MAX7219 控制芯片。
27. `PORTB&=~(1<<PB4);`:将 PB4 设为低电平,开始数据传输。
28. `SPI_MasterTransmit(address);`:向 SPI 总线发送地址信息。
29. `SPI_MasterTransmit(data);`:向 SPI 总线发送数据信息。
30. `PORTB|=(1<<PB4);`:将 PB4 设为高电平,结束数据传输。
31. `void SPI_MasterTransmit(unsigned char cData)`:向 SPI 总线传输数据。
32. `unsigned char tmp;`:定义 tmp 变量,用于暂存 SPI 状态寄存器。
33. `PORTB&=(1<<PB7);`:将 PB7 设为低电平,开始 SPI 数据传输。
34. `tmp=SPSR;`:将 SPI 状态寄存器中的值存储到 tmp 变量中。
35. `SPDR=cData;`:将要发送的数据存储到 SPI 数据寄存器中。
36. `while(!(SPSR&(1<<SPIF)));`:等待 SPI 传输完成。
37. `#pragma interrupt_handler timer1_compa_isr:20`:定义定时器 1 比较匹配中断函数。
38. `void timer1_compa_isr(void)`:定时器 1 比较匹配中断函数。
39. `i++;`:每次进入中断,i 自增。
40. `if(i%200==0)`:每个 200 毫秒更新一次数码管显示。
41. `a++;`:计时器自增。
42. `if(a==9999)`:当计时器达到 9999 时,将其重置为 0。
43. `#pragma interrupt_handler ext_int1_isr:3`:定义外部中断 1 中断函数。
44. `void ext_int1_isr(void)`:外部中断 1 中断函数。
45. `switch (aw) {`:根据 aw 变量的值进行判断。
46. `case 0:`:当 aw 为 0 时,启动计时器。
47. `TCCR0=0b00001000;`:设置计时器 0 的工作模式为普通模式,不分频。
48. `aw=1;`:将 aw 设置为 1。
49. `break;`:跳出 switch。
50. `case 1:`:当 aw 为 1 时,停止计时器。
51. `TCCR0=0b00001101;`:设置计时器 0 的工作模式为 CTC 模式,不分频。
52. `aw=0;`:将 aw 设置为 0。
53. `break;`:跳出 switch。
54. `void main(void)`:主函数。
55. `unsigned int b,c,d,e;`:定义多个 unsigned int 类型的变量。
56. `port_init();`:初始化端口。
57. `SPCR=(1<<MSTR)|(1<<SPE)|(1<<SPR0);`:设置 SPI 控制寄存器,主模式,使能 SPI,波特率分频为 16。
58. `init_devices();`:初始化设备。
59. `init_max7219();`:初始化 MAX7219 控制芯片。
60. `TCCR0=0b00001000;`:设置计时器 0 的工作模式为普通模式,不分频。
61. `OCR0=0b00000100;`:设置计时器 0 的比较值为 4。
62. `TIMSK=0b00000010;`:使能计时器 0 的比较匹配中断。
63. `MCUCR=0x0A; GICR|=0xC0;`:设置外部中断 1 的触发方式为下降沿触发,并使能外部中断 1。
64. `send_max7219(1,0);`:清空数码管。
65. `send_max7219(2,0);`:清空数码管。
66. `send_max7219(3,0);`:清空数码管。
67. `send_max7219(4,0);`:清空数码管。
68. `TCCR0=0b00001101;`:设置计时器 0 的工作模式为 CTC 模式,不分频。
69. `while (1)`:死循环。
70. `if(i%200==0)`:每个 200 毫秒更新一次数码管显示。
71. `send_max7219(4,e=a/1000);`:将千位数码管显示为计时器的千位数。
72. `send_max7219(3,d=((a-e*1000)/100));`:将百位数码管显示为计时器的百位数。
73. `send_max7219(2,c=((a-e*1000-d*100)/10));`:将十位数码管显示为计时器的十位数。
74. `send_max7219(1,b=a%10);`:将个位数码管显示为计时器的个位数。
阅读全文