|
本帖最后由 karajanlee 于 2014-1-17 16:05 编辑
如题,真的是纯属好玩,用串口接收数据,单独的MCU来显示数据,所以不会闪烁,可以减轻主MCU的运算压力。。哈哈。。
电路图
洞洞板效果,数码管叠在MCU上。。。
- /**
- * 基于STC15W204S的串口4位LED驱动模块
- *
- * 串口波特率: 9600 bps
- * 单次发送数据长度: 8 位
- * 格式:
- * 字符索引1 控制位1 ... 字符索引4 控制位4
- * 字符索引列表:
- * 00 -> 0, 01 -> 1, 02 -> 2, 03 -> 3, 04 -> 4,
- * 05 -> 5, 06 -> 6, 07 -> 7, 08 -> 8, 09 -> 9,
- * 0A -> -, 0B -> A, 0C -> b, 0D -> c, 0E -> d,
- * 0F -> E, 10 -> F, 11 -> g, 12 -> H, 13 -> J,
- * 14 -> L, 15 -> n, 16 -> o, 17 -> p, 18 -> q,
- * 19 -> r, 1A -> S, 1B -> t, 1C -> U, 1D -> y,
- * 控制位:
- * -----------------------------------------------------------
- * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * |---------------------------------------------------------|
- * | x | x | x | x | x | x | 0/1 | 0/1 |
- * |---------------------------------------------------------|
- * | 0:| 不显示小数点 | 不显示当前位字符 |
- * | 1:| 显示小数点 | 显示当前位字符 |
- * -----------------------------------------------------------
- *
- * No license applied. Use as you wish.
- * Happy Coding!
- *
- * 2014 (c) K% Design
- * by HouYu Li <lihouyu@phpex.net>
- */
- #include <INTRINS.H>
- #include <STC/STC15F2K60S2.H>
- sbit CommD1 = P1 ^ 1; // 数字1(最高位)共阴极 P1.1
- sbit CommD2 = P3 ^ 6; // 数字2共阴极 P3.6
- sbit CommD3 = P3 ^ 3; // 数字3共阴极 P3.3
- sbit CommD4 = P5 ^ 5; // 数字4共阴极 P5.5
- unsigned char MaskCommD1 = 0x02; // 数字1共阴极Byte表示形式
- unsigned char MaskCommD2D3 = 0x48; // 数字2,3共阴极合并Byte表示形式
- unsigned char MaskCommD4 = 0x20; // 数字4共阴极Byte表示形式
- unsigned char UARTPINEN = 0x03; // 置高P3.0, P3.1使串口工作正常
- /**
- * 以下是各个字符的段码,由于没有足够的IO,并简化了硬件连接
- * 所以导致需要三组端口配合来实现字符显示
- */
- unsigned char P1SEG[30] = {0x2D, 0x20, 0x0D, 0x29, 0x20,
- 0x29, 0x2D, 0x21, 0x2D, 0x29,
- 0x00, 0x25, 0x2C, 0x0C, 0x2C,
- 0x0D, 0x05, 0x29, 0x24, 0x28,
- 0x0C, 0x24, 0x2C, 0x05, 0x21,
- 0x04, 0x29, 0x0C, 0x2C, 0x28};
- /* 为了节约内存,改用switch选择语句
- unsigned char P3SEG[30] = {0x84, 0x04, 0x04, 0x04, 0x84,
- 0x80, 0x80, 0x04, 0x84, 0x84,
- 0x00, 0x84, 0x80, 0x00, 0x04,
- 0x80, 0x80, 0x84, 0x84, 0x04,
- 0x80, 0x00, 0x00, 0x84, 0x84,
- 0x00, 0x80, 0x80, 0x84, 0x84};
- unsigned char P5SEG[30] = {0x00, 0x00, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x00, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x00,
- 0x00, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x00, 0x10};
- */
- /** // */
- // 串口接收数据缓存
- unsigned char UARTBUFF[8] = {0, 0x01, 0, 0x03, 0, 0x01, 0, 0x01};
- // 串口接收自己位置索引
- unsigned char idxUARTBUFF = 0;
- // 存放显示数据
- unsigned char DISPBUFF[8] = {1, 0x01, 2, 0x03, 3, 0x01, 4, 0x01};
- // 接收数据长度
- unsigned char BUFFLEN = 8;
- // 数据是否接受完毕
- char RXDONE = 0;
- //char TXBUSY = 0;
- void initIO();
- void showChar(unsigned char idx, unsigned char segidx, unsigned char ctrl);
- /**
- * 以下代码由STC刷机工具生成
- */
- void Delay1ms();
- void initUart(void);
- void Delay1ms() //@11.0592MHz
- {
- unsigned char i, j;
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- void initUart(void) //9600bps@11.0592MHz
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x04; //定时器2时钟为Fosc,即1T
- T2L = 0xE0; //设定定时初值
- T2H = 0xFE; //设定定时初值
- AUXR |= 0x01; //串口1选择定时器2为波特率发生器
- AUXR |= 0x10; //启动定时器2
-
- // 以下2行代码自行添加
- EA = 1; //启用系统总中断和串口中断
- ES = 1;
- }
- /** // */
- /**
- * 初始化IO
- */
- void initIO() {
- // 将所有驱动LED的IO设置成强推挽模式
- // 除了P3.0, P3.1
- P1M0 = 0x3D + MaskCommD1;
- P3M0 = 0x84 + MaskCommD2D3;
- P5M0 = 0x10 + MaskCommD4;
- // 将IO赋初始值
- // 共阴极IO置高
- // 字符段IO置低
- // 保持P3.0, P3.1为高
- P1 = MaskCommD1;
- P3 = MaskCommD2D3 + UARTPINEN;
- P5 = MaskCommD4;
- }
- /**
- * 显示字符
- * 参数:idx 显示第几个字符,从左到右顺序为1,2,3,4
- * 参数:segidx 要显示的字符索引值
- * 参数:ctrl 当前字符的控制位
- */
- void showChar(unsigned char idx, unsigned char segidx, unsigned char ctrl) {
- if (ctrl & 1 && idx < 30) { // 确认当前字符的索引值有效
- // 要同时设置好P1, P3和P5才能正常显示字符
- // 设置Port1
- P1 = P1SEG[segidx] + MaskCommD1;
- // 设置Port3
- //P3 = P3SEG[segidx] + MaskCommD2D3 + UARTPINEN;
- switch (segidx) {
- case 1:
- case 2:
- case 3:
- case 7:
- case 14:
- case 19:
- P3 = 0x04 + MaskCommD2D3 + UARTPINEN;
- break;
- case 10:
- case 13:
- case 21:
- case 22:
- case 25:
- P3 = MaskCommD2D3 + UARTPINEN;
- break;
- case 5:
- case 6:
- case 12:
- case 15:
- case 16:
- case 20:
- case 26:
- case 27:
- P3 = 0x80 + MaskCommD2D3 + UARTPINEN;
- break;
- default:
- P3 = 0x84 + MaskCommD2D3 + UARTPINEN;
- break;
- }
- // 设置Port5
- //P5 = P5SEG[segidx] + MaskCommD4;
- switch (segidx) {
- case 0:
- case 1:
- case 7:
- case 9:
- case 20:
- case 28:
- P5 = MaskCommD4;
- break;
- default:
- P5 = 0x10 + MaskCommD4;
- break;
- }
-
- // 是否显示小数点
- if (ctrl & 2)
- P1 |= 0x10;
-
- // 置低相应位的共阴极IO
- switch (idx) {
- case 1:
- CommD1 = 0;
- break;
- case 2:
- CommD2 = 0;
- break;
- case 3:
- CommD3 = 0;
- break;
- case 4:
- CommD4 = 0;
- break;
- }
- }
- }
- /**
- * 主函数
- */
- void main() {
- initIO(); // 初始化IO
- initUart(); // 初始化串口
-
- while (1) {
- if (RXDONE == 1) {
- /**
- while (TXBUSY);
- TXBUSY = 1;
- SBUF = DISPBUFF[4];
- */
- RXDONE = 0;
- // 当接收完数据后重置IO,准备显示新的数字
- P1 = MaskCommD1;
- P3 = MaskCommD2D3 + UARTPINEN;
- P5 = MaskCommD4;
- }
- showChar(1, DISPBUFF[0], DISPBUFF[1]);
- Delay1ms();
- showChar(2, DISPBUFF[2], DISPBUFF[3]);
- Delay1ms();
- showChar(3, DISPBUFF[4], DISPBUFF[5]);
- Delay1ms();
- showChar(4, DISPBUFF[6], DISPBUFF[7]);
- Delay1ms();
- }
- }
- /**
- * 串口中断
- */
- void UART() interrupt 4 using 1 {
- if (RI) {
- RI = 0;
- UARTBUFF[idxUARTBUFF] = SBUF;
- idxUARTBUFF++;
- // 当接收完指定长度(BUFFLEN)的数据之后
- // 把串口接收数据缓存的数据复制到显示的缓存中
- // 同时重置了串口接收缓存位置索引
- if (idxUARTBUFF == BUFFLEN) {
- while (idxUARTBUFF > 0) {
- idxUARTBUFF--;
- DISPBUFF[idxUARTBUFF] = UARTBUFF[idxUARTBUFF];
- }
- RXDONE = 1;
- }
- }
- /**
- if (TI) {
- TI = 0;
- TXBUSY = 0;
- }
- */
- }
复制代码
|
|