|
本帖最后由 广东梁百万 于 2024-6-10 21:02 编辑
之前用TM1640做单片机的外置LED显示驱动,很方便,可以驱动16个8字共阴数码管,
因为有几次用8脚单片机,I/O口少,只能外接一两个按键, 于是想用TM1639做显示驱动和按键输入。
6月6晚开始编写,经过几晚的折腾,终于测试成功了。适用于C51单片机。
现在分享给大家。 我是单片机新手,写的程序很啰嗦,如有错误,欢迎指导,共同学习。
原验证程序有很多,我把与之无关的删除了,下面贴出程序的是TM1639和相关部分, 在SecJC()函数里面有简单测试--用cnt2计数并显示,按键按下情况在第8个数码管(我测试板上是8个LED灯)指示。
使用说明:
数组 TM1639_DATA[8] 里面的数值就是8个数码管, 每个数的8位(b0~b7) 对应数码管的 a , b , c ,d ,e , f , g , dp ,
如果需要显示0~9,ABCDEF 这些数字,那就要先调用 void TM1639_BCD_OUT(); 转换函数, 函数里面那个变量 i 是需要转换的数码管数量,
假如我8个数码管全部显示数字,那这个i 就设置8 ,数字内容从LED_BCD[ ]数组输入; 假如我只显示4个数码管, 其他的作指示灯用, 那个 i 就设置4,数字内容从LED_BCD[ ]数组输入, 指示灯内容从TM1639_DATA[ ] 输入。
程序对应这个电路
- //-------广东梁百万,2024年6月6日
- //------STC8H1K_TM1639_验证程序
- /*
- 使用说明:
- 数组 TM1639_DATA[8] 里面的数值就是8个数码管, 每个数的8位(b0~b7) 对应数码管的 a , b , c ,d ,e , f , g , dp ,
- 如果需要显示0~9,ABCDEF 这些数字,那就要先调用 void TM1639_BCD_OUT(); 转换函数, 函数里面那个变量 i 是需要转换的数码管数量,
- 假如我8个数码管全部显示数字,那这个i 就设置8 ,数字内容从LED_BCD[ ]数组输入; 假如我只显示4个数码管, 其他的作指示灯用, 那个 i 就设置4,数字内容从LED_BCD[ ]数组输入, 指示灯内容从TM1639_DATA[ ] 输入。
- */
- #include<stc8g.h>
- #include "intrins.h"
- sbit TM16_DIN = P1^4; //TM1640的串口数据输入DI P14
- sbit TM16_SCK = P1^5; //TM1640的时钟输入SCK P15
- sbit TM16_STB = P1^6; //TM1640的片选端STB P16
- unsigned int cnt1=0,cnt2=0;
- unsigned char xdata LED_BCD[8] = {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- unsigned char xdata TM1639_DATA[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};//显示的数据, 可在其他程序里对本数组的内容真的操作改变显示内容, 最前位对应TM1639的GRID1
- unsigned char xdata LED_OF[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,}; //数位熄灭控制,0x00是灭,0xff是显示
- unsigned char xdata tm16_dp[8]={0,0,0,0,0,0,0,0,}; //存放各数位的小数点
- unsigned char bdata tm16_dp_tmp=0; // 小数点专用
- sbit tm16_tmp_bit7=tm16_dp_tmp^7 ;// 小数点专用位
- unsigned char xdata TM1639_command1=0x40;//数据设置
- unsigned char xdata TM1639_command2=0xc0;//地址设置
- unsigned char xdata TM1639_command3=0x8A;//显示模式与亮度
- unsigned char bdata TM1639_KEY_DATA=0x00;
- //TM1639的按键数据,对应 B7 B6 B5 B4 B3 B2 B1 B0
- // K1-KS4 K1-KS3 K1-KS2 K1-KS1 K0-KS4 K0-KS3 K0-KS2 K0-KS1
- //bdata数据类型便于另一个按键扫描程序提取按键值
-
- sbit TM1639_KEY_B0=TM1639_KEY_DATA^0; // 定义位变量,用于另一个按键扫描程序提取按键值
- sbit TM1639_KEY_B1=TM1639_KEY_DATA^1;
- sbit TM1639_KEY_B2=TM1639_KEY_DATA^2;
- sbit TM1639_KEY_B3=TM1639_KEY_DATA^3;
- sbit TM1639_KEY_B4=TM1639_KEY_DATA^4;
- sbit TM1639_KEY_B5=TM1639_KEY_DATA^5;
- sbit TM1639_KEY_B6=TM1639_KEY_DATA^6;
- sbit TM1639_KEY_B7=TM1639_KEY_DATA^7;
-
- //----------------------------
-
- void TM1639_LED(); //TM1639共阴LED驱动
- void TM1639_BCD_OUT(); //TM1639BCD数转显示代码
- void TM1639_KEY(); //TM1639按键读出程序
- //------------------------------
- void SecJC(); //1ms循环定时处理程序
-
- #define MAIN_Fosc 11059200L //定义主时钟, 自定义变量 ,L是长整型的意思
- void main()
- {
- P0M0=0x00;
- P0M1=0x00;
- P1M0=0x00;
- P1M1=0x00;
- P2M0=0x00;
- P2M1=0x00;
- P3M0=0x00;
- P3M1=0x00;
- P5M0=0x00;
- P5M1=0x00;
- TM16_DIN =1;
- TM16_SCK =1;
- TM16_STB =1;
- P_SW2 =0xB0; //D7位控制访问扩展SFR特殊寄存器 ,D4 D5位控制选用某端口做I2C的SCL SDA
- AUXR |= 0x04; //定时器时钟1T模式 定时器2设置
- T2L = 0xcd;// //设置定时初值 0.5ms是0x66;// 1ms是0xcd; 11.0592Mhz
- T2H = 0xd4;// //设置定时初值 0.5ms是0xea;// 1ms是0xd4;
- AUXR |= 0x10; //定时器2开始计时
- IE2 = 0x04;
- EA = 1; //中断使能
- //主函数//********************
- while (1)
- {
- //重复循环
- _nop_();
- }
- }
- ////////////////***********************
- ///定时处理/
- void SecJC() //定时处理
- {
- TM1639_KEY(); //TM1639按键读出程序
- cnt1++;
- if(cnt1>=20)
- {
- TM1639_BCD_OUT(); //TM1639BCD显示代码转换
- TM1639_LED(); //TM1639共阴LED驱动***************
- cnt1=0;
- cnt2++;
- LED_BCD[3] =cnt2%10; //显示计数
- LED_BCD[2] =cnt2/10%10;
- LED_BCD[1] =cnt2/100%10;
- LED_BCD[0] =cnt2/1000%10;
-
- TM1639_DATA[7]=TM1639_KEY_DATA; // 显示按键情况
- }
- }
- //------------------------------------------------------
- //* 定时器2中断服务函数 */
- void InterruptTimer2() interrupt 12
- {
-
- SecJC();//定时处理
- }
- //**************************************
-
-
- //TM1639--共阴LED驱动
- void TM1639_LED() //TM1639共阴LED驱动1
- {
- unsigned char xdata i,j=0,k=0;
- unsigned char xdata tmp1; //临时缓存
- unsigned char xdata TM1639_DATA_TMP[16]; //临时缓存组,因为TM1639的特性,需把8个字节数据拆分成16个低位半字节
-
- for(i=0;i<16;i++) //这个i是转换的个数
- {
- TM1639_DATA_TMP[i]=TM1639_DATA[j];
- i++;
- TM1639_DATA_TMP[i]=TM1639_DATA[j];
- TM1639_DATA_TMP[i]=TM1639_DATA_TMP[i]>>4; //把高4位移到低4位
- j++;
- }
- i=0;
- j=0;
-
- TM16_DIN =1; //数据和时钟端口拉高
- TM16_SCK =1;
- TM16_STB =1; //片选拉高
-
-
- TM16_STB =0;//片选拉低
- TM16_STB =0;//片选拉低
- TM16_DIN = 0; //开始位
- nop_();
- TM16_SCK =0; //开始位
- nop_();
-
- tmp1=TM1639_command1; //先发送数设置字节
- for(i=0; i<8; i++)
- {
- tmp1>>=1;//低位移出到CY
- TM16_DIN = CY;
-
- TM16_SCK =1;
- nop_();
- nop_();
-
- TM16_SCK =0;
- nop_();
-
- TM16_DIN =0;
- }
- TM16_SCK =1; //停止位
- nop_();
-
- TM16_DIN =1; //停止位
- nop_();
-
- TM16_STB =1; //片选拉高
- nop_();
- nop_();
-
- TM16_STB =0;//片选拉低
- nop_();
- nop_();
-
- TM16_DIN = 0; //开始位
- nop_();
-
- TM16_SCK =0; //开始位
- nop_();
- tmp1=TM1639_command2; //再发送地址字节
- for(i=0; i<8; i++)
- {
- tmp1>>=1;//低位移出到CY
- TM16_DIN = CY;
-
- TM16_SCK =1;
- nop_();
- nop_();
-
- TM16_SCK =0;
- nop_();
-
- TM16_DIN =0;
- }
- for(j=0; j<16; j++) //j是LED数码管显示个数***************
- {
- tmp1=TM1639_DATA_TMP[k];
- for(i=0; i<8; i++)
- {
- tmp1>>=1;//低位移出到CY
- TM16_DIN = CY;
-
- TM16_SCK =1;
- nop_();
- nop_();
-
- TM16_SCK =0;
- nop_();
-
- TM16_DIN =0;
- }
-
- k++;
-
- }
-
- TM16_SCK =1; //停止位
- nop_();
-
- TM16_DIN =1; //停止位
- nop_();
-
- TM16_STB =1; //片选拉高
- nop_();
- nop_();
- TM16_STB =0;//片选拉低
- nop_();
- nop_();
-
-
- TM16_DIN = 0; //开始位
- nop_();
-
- TM16_SCK =0; //开始位
- nop_();
- tmp1=TM1639_command3; //发送亮度控制字节
- for(i=0; i<8; i++)
- {
- tmp1>>=1;//低位移出到CY
- TM16_DIN = CY;
-
- TM16_SCK =1;
- nop_();
- nop_();
-
- TM16_SCK =0;
- nop_();
-
- TM16_DIN =0;
- }
- TM16_SCK =1; //停止位
- nop_();
- TM16_DIN =1; //停止位
- nop_();
-
- TM16_STB =1; //片选拉高
- nop_();
- nop_();
-
- }
-
-
- //TM1639,BCD数转显示代码
- void TM1639_BCD_OUT() //TM1639BCD数转显示代码
- {
- unsigned char xdata i=0,j=0;
- unsigned char code LED_JH[18] = { //数值与显示段码转换
- 0x3f,0x06,0x5B,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80
- };
-
- for(i=0;i<4;i++) //这个i是转换的显示个数********** 8是8个LED数码管
- {
- TM1639_DATA[j]=LED_JH[(LED_BCD[j])]; //LED_BCD[k]j是需要显示的数据,LED_JH是预存的转换代码
- //LED_OUTA[k]是转换代码结果 //对LED_OUTA[k]某位写入0x00可实现不显示
- TM1639_DATA[j]=TM1639_DATA[j] & LED_OF[j];//数位熄灭控制,根据需要控制某位熄灭。
- tm16_dp_tmp=TM1639_DATA[j];//先把显示代码放到可位操作的bdata类型的缓存上
- tm16_tmp_bit7=tm16_dp[j];//再对小数点bit7位操作,小数点控制数放在tm16_dp[j]数组上。
- TM1639_DATA[j]=tm16_dp_tmp;//最后再放回到显示代码输出数组
-
- j++;
- }
- }
- //******************************************
-
- // TM1639按键读出程序
-
- void TM1639_KEY() //TM1639按键读出程序
- {
- unsigned char xdata i,j=0,k=0;
- unsigned char xdata TM1639_tmp1; //临时缓存
- unsigned char xdata TM1639_tmp2; //临时缓存
- unsigned char xdata TM1639_tmp3; //临时缓存
- unsigned char xdata TM1639_KEY_N[2];
-
- TM16_DIN =1; //数据和时钟端口拉高
- TM16_SCK =1;
- TM16_STB =1; //片选拉高
-
- TM16_STB =0;//片选拉低
- TM16_STB =0;//片选拉低
- TM16_DIN = 0; //开始位
- nop_();
- TM16_SCK =0; //开始位
- nop_();
- TM1639_command1=0X42; // 设置命令字节是读出按键
- TM1639_tmp1=TM1639_command1; //先发送数设置字节
- for(i=0; i<8; i++)
- {
- TM1639_tmp1>>=1;//低位移出到CY
- TM16_DIN = CY;
-
- TM16_SCK =1;
- nop_();
- nop_();
-
- TM16_SCK =0;
- nop_();
-
- TM16_DIN =0;
- }
- TM16_SCK =1; //停止位
- nop_();
-
- TM16_DIN =1; //停止位
- nop_();
- nop_();
- nop_();
-
-
- // TM16_DIN = 0; //开始位
- nop_();
-
- TM16_SCK =0; //开始位
- nop_();
- for(j=0; j<2; j++) //j读出数据个数***************
- {
- //TM1639_KEY_N[k]=tmp1;
- for(i=0; i<8; i++)
- {
- TM16_SCK =1;
- nop_();
- nop_();
- nop_();
- nop_();
-
- TM1639_KEY_N[k]=(TM1639_KEY_N[k]<<1)| TM16_DIN;
-
- TM16_SCK =0;
- nop_();
-
- //TM16_DIN =0;
- }
- k++;
- }
- TM16_SCK =1; //停止位
- nop_();
- TM16_DIN =1; //停止位
- nop_();
-
- TM16_STB =1; //片选拉高
-
- TM1639_tmp1=TM1639_KEY_N[0]; //整理K0-ks1,ks2 数值
- TM1639_tmp1=TM1639_tmp1>>5;
- TM1639_tmp1=TM1639_tmp1 & 0x01;
- TM1639_tmp2=TM1639_KEY_N[0];
- TM1639_tmp2=TM1639_tmp2&0x02;
- TM1639_tmp3=TM1639_tmp1|TM1639_tmp2;
- TM1639_tmp1=TM1639_KEY_N[1]; //整理K0-ks3,ks4 数值
- TM1639_tmp1=TM1639_tmp1>>3;
- TM1639_tmp1=TM1639_tmp1 & 0x04;
- TM1639_tmp2=TM1639_KEY_N[1];
- TM1639_tmp2=TM1639_tmp2<<2;
- TM1639_tmp2=TM1639_tmp2&0x08;
- TM1639_tmp3=TM1639_tmp1|TM1639_tmp2|TM1639_tmp3;
-
- TM1639_tmp1=TM1639_KEY_N[0]; //整理K1-ks1,ks2 数值
- TM1639_tmp1=TM1639_tmp1>>2;
- TM1639_tmp1=TM1639_tmp1 & 0x10;
- TM1639_tmp2=TM1639_KEY_N[0];
- TM1639_tmp2=TM1639_tmp2<<3;
- TM1639_tmp2=TM1639_tmp2 & 0x20;
- TM1639_tmp2=TM1639_tmp2|TM1639_tmp1;
- TM1639_tmp3=TM1639_tmp3|TM1639_tmp2;
-
- TM1639_tmp1=TM1639_KEY_N[1]; //整理K1-ks3,ks4 数值
- TM1639_tmp1=TM1639_tmp1 & 0x40;
- TM1639_tmp2=TM1639_KEY_N[1];
- TM1639_tmp2=TM1639_tmp2<<5;
- TM1639_tmp2=TM1639_tmp2 & 0x80;
- TM1639_tmp2=TM1639_tmp2|TM1639_tmp1;
- TM1639_tmp3=TM1639_tmp3|TM1639_tmp2;
-
- TM1639_KEY_DATA= TM1639_tmp3; //读出的按键值合并在 TM1639_KEY_DATA寄存上。
- // TM1639_KEY_DATA的按键数据, B7 B6 B5 B4 B3 B2 B1 B0
- // 对应按键 K1-KS4 K1-KS3 K1-KS2 K1-KS1 K0-KS4 K0-KS3 K0-KS2 K0-KS1
-
- }
复制代码
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|