LabVIEW版本:LabVIEW2015 32位
51单片机:STC89C52RC
Keil版本:μVision V5.14.2
数码管模块:TM1638数码管控制模块
LabVIEW通过串口连接51单片机控制数码管的显示
/**
***************************************************************************************
* 文 件:工程主函数文件
* 芯 片:STC89C52RC
* 创 建:hx
* 时 间:2018-8-21
***************************************************************************************
*/
#include //51系列单片机头文件
#include "tm1638.h" //TM1638模块实现头文件
#include "uart.h" //串口实现头文件
sbit LED0 = P2^0; //LED0
sbit LED1 = P2^1; //LED1
/**
***************************************************************************************
* 函 数:工程主函数
* 参 数:无
* 返回值:无
***************************************************************************************
*/
void main()
{
unsigned int num=0; //计数
TM1638_Init(); //TM1638初始化
UART_Init(); //串口初始化
while(1)
{
num++;
if(num==30000)
{
LED0 = !LED0; //LED0亮灭转换,指示程序正常运行
num = 0;
}
if(RxComplete == 1) //接收完成
{
TM1638_Tube(TubeDispCmd[0],TubeDispCmd[1],TubeDispCmd[2]); //数码管显示
RxComplete = 0; //清除接收完成标志
}
}
}
/**
***************************************************************************************
* 文 件:TM1638模块实现头文件
* 创 建:hx
* 时 间:2018-6-21
***************************************************************************************
*/
void TM1638_WriteData(unsigned char Data); //TM1638写数据函数
void TM1638_WriteAddressData(unsigned char addr,unsigned char Data); //TM1638指定地址写数据函数
unsigned char TM1638_Read(void); //TM1638读数据函数
void TM1638_Light(unsigned char light,unsigned char state); //TM1638指定LED灯亮灭函数
/** 参 数:light:LED灯序号;0:选中所有LED灯;1~8:选中第1~8个LED灯;
* 参 数:state:0灭1亮 */
void TM1638_Tube(unsigned char tube,unsigned char num,unsigned char state); //TM1638数码管显示函数
/** 参 数:tube:数码管序号;0:选中所有数码管;1~8:选中第1~8个数码管;
* 参 数:num:要显示的数字,0-F;16:-;
* 参 数:state:状态,0不带小数点,1带小数点,2灭 */
unsigned char TM1638_ReadKey(void); //TM1638读键扫数据函数
/** 返回值:读取的按键号,1~8;无按键按下时返回0 */
void TM1638_Init(void); //TM1638初始化函数
/**
***************************************************************************************
* 文 件:TM1638模块实现源文件
* 创 建:hx
* 时 间:2018-6-21
***************************************************************************************
*/
#include //51系列单片机头文件
#include "tm1638.h" //TM1638模块实现头文件
sbit STB = P1^0; //STB
sbit CLK = P1^1; //CLK
sbit DIO = P1^2; //DIO
unsigned char TUBE[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, //共阴极数码管段码,不带小数点
// 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40}; //0~F,1亮0灭
// 8 , 9 , A , b , C , d , E , F , - ,
unsigned char TUBE_P[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87, //共阴极数码管段码,带小数点
// 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
0xFF,0xEF,0xF7,0xFC,0xB9,0xDE,0xF9,0xF1,0xC0}; //0~F,1亮0灭
// 8 , 9 , A , b , C , d , E , F , - ,
/**
***************************************************************************************
* 函 数:TM1638写数据函数
* 参 数:Data:要写入的8位数据
* 返回值:无
***************************************************************************************
*/
void TM1638_WriteData (unsigned char Data) //TM1638写数据函数
{
unsigned char i; //计数变量
for(i=0;i<8;i++) //循环写入8位数据
{
CLK = 0; //CLK=0
if(Data&0x01) //从低位开始写入
{
DIO = 1; //DIO=1
}
else
{
DIO = 0; //DIO=0
}
Data>>=1;
CLK = 1; //CLK=1
}
}
/**
***************************************************************************************
* 函 数:TM1638指定地址写数据函数
* 参 数1:addr:要写入数据的地址
* 参 数2:Data:要写入的8位数据
* 返回值:无
***************************************************************************************
*/
void TM1638_WriteAddressData(unsigned char addr,unsigned char Data) //TM1638指定地址写数据函数
{
STB = 0; //STB=0
TM1638_WriteData(addr); //地址
TM1638_WriteData(Data); //数据
STB = 1; //STB=1
}
/**
***************************************************************************************
* 函 数:TM1638读数据函数
* 参 数:无
* 返回值:读取的8位数据
***************************************************************************************
*/
unsigned char TM1638_Read(void) //TM1638读数据函数
{
unsigned char i,temp=0;
DIO = 1; //DIO=1,设置为输入
for(i=0;i<8;i++)
{
temp>>=1; //从高位往地位读取
CLK = 0; //CLK=0
if(DIO)
{
temp|=0x80; //按位或:与0或不变、与1或置1
}
CLK = 1; //CLK=1
}
return temp;
}
/**
***************************************************************************************
* 函 数:TM1638指定LED灯亮灭函数
* 参 数:light:LED灯序号,1~8;0:选中所有LED灯
* 参 数:state:0灭1亮
* 返回值:无
***************************************************************************************
*/
void TM1638_Light(unsigned char light,unsigned char state) //TM1638指定LED灯亮灭函数
{
unsigned char i = 0; //计数变量
if((light>=1)&&(light<=8)) //指定第1~8个LED灯的亮灭
{
if(state) //指定LED灯亮,state=1
{
TM1638_WriteAddressData(0XC0+2*(light-1)+1,0X01); //LED灯亮
}
else //指定LED灯灭,state=0
{
TM1638_WriteAddressData(0XC0+2*(light-1)+1,0X00); //LED灯灭
}
}
else if(light==0) //指定所有LED灯的亮灭
{
if(state) //所有LED灯亮,state=1
{
for(i=0;i<8;i++) //循环点亮所有LED灯
{
TM1638_WriteAddressData(0XC0+2*i+1,0X01); //LED灯亮
}
}
else //所有LED灯灭,state=0
{
for(i=0;i<8;i++) //循环熄灭所有LED灯
{
TM1638_WriteAddressData(0XC0+2*i+1,0X00); //LED灯灭
}
}
}
}
/**
***************************************************************************************
* 函 数:TM1638数码管显示函数
* 参 数:tube:数码管序号,1-8;0:选中全部数码管
* 参 数:num:要显示的数字,0-F
* 参 数:state:状态,0不带小数点,1带小数点,2灭
* 返回值:无
***************************************************************************************
*/
void TM1638_Tube(unsigned char tube,unsigned char num,unsigned char state) //TM1638数码管显示函数
{
unsigned char i = 0; //计数变量
if(state==0) //不带小数点
{
if((tube>=1)&&(tube<=8)) //指定1~8号数码管
{
TM1638_WriteAddressData(0XC0+2*(tube-1),TUBE[num]); //指定数码管tube显示num,不带小数点
}
else if(tube==0) //指定所有数码管
{
for(i=0;i<8;i++) //所有数码管显示同一数字num
{
TM1638_WriteAddressData(0XC0+2*i,TUBE[num]); //所有数码管显示同一数字num,不带小数点
}
}
}
else if(state==1) //带小数点
{
if((tube>=1)&&(tube<=8)) //指定1~8号数码管
{
TM1638_WriteAddressData(0XC0+2*(tube-1),TUBE_P[num]); //指定数码管tube显示num,带小数点
}
else if(tube==0) //指定所有数码管
{
for(i=0;i<8;i++) //所有数码管显示同一数字num
{
TM1638_WriteAddressData(0XC0+2*i,TUBE_P[num]); //所有数码管显示同一数字num,带小数点
}
}
}
else if(state==2) //数码管熄灭
{
if((tube>=1)&&(tube<=8)) //指定1~8号数码管
{
TM1638_WriteAddressData(0XC0+2*(tube-1),0x00); //指定数码管tube熄灭
}
else if(tube==0) //指定所有数码管
{
for(i=0;i<8;i++) //所有数码管熄灭
{
TM1638_WriteAddressData(0XC0+2*i,0x00); //所有数码管熄灭
}
}
}
}
/**
***************************************************************************************
* 函 数:TM1638读键扫数据函数
* 参 数:无
* 返回值:读取的按键号,1~8,无按键按下时返回0
***************************************************************************************
*/
unsigned char TM1638_ReadKey(void) //TM1638读键扫数据函数
{
unsigned char c[4],i,key_value=0;
STB = 0; //STB=0,开始写命令
TM1638_WriteData(0x42); //普通模式,地址自动增加,读键扫数据
for(i=0;i<250;i++); //此处需要一个等待时间,最少1us
for(i=0;i<4;i++) //循环读取键值
{
c[i]=TM1638_Read(); //读取键值
}
STB = 1; //STB=1,读键值结束
for(i=0;i<4;i++)
{
if(c[i]!=0)
{
key_value = 2*i+(c[i]+14)/15;
key_value = (key_value+7*(1-key_value%2)+1)/2; //获取按键值(1-8)
break;
}
}
return key_value; //返回按键值,0或1~8
}
/**
***************************************************************************************
* 函 数:TM1638初始化函数
* 参 数:无
* 返回值:无
***************************************************************************************
*/
void TM1638_Init(void) //TM1638初始化函数
{
unsigned char i; //计数变量
STB = 0; //STB=0
TM1638_WriteData(0x44); //普通模式,固定地址,写数据到显示寄存器
STB = 1; //STB=1
STB = 0; //STB=0
TM1638_WriteData(0x88); //显示开,亮度第1级
STB = 1; //STB=1
for(i=0;i<16;i++) //熄灭所有灯与数码管
{
TM1638_WriteAddressData(0XC0+i,0X00); //全地址写入0X00
}
}
/**
***************************************************************************************
* 工 程:串口实现头文件
* 芯 片:STC89C52RC
* 创 建:hx
* 时 间:2018-7-24
***************************************************************************************
*/
extern unsigned char RxComplete; //接收完成标志
extern unsigned char TubeDispCmd[3]; //数码管显示命令
void UART_SendChar(char chr); //串口发送单个字符函数
void UART_SendString(char *str); //串口发送字符串函数
void UART_SendInt(int intNum); //串口发送整型int(4)函数
void UART_SendFloat(float fNum); //串口发送实型float(4)函数
void UART_Init(void); //串口初始化函数
/**
***************************************************************************************
* 工 程:串口实现源文件
* 芯 片:STC89C52RC
* 创 建:hx
* 时 间:2018-7-24
***************************************************************************************
*/
#include //51系列单片机头文件
#include "uart.h" //串口实现头文件
#include "tm1638.h" //TM1638模块实现头文件
//sbit LED0 = P2^0;
//sbit LED1 = P2^1;
unsigned char dataCount = 0; //接收数据计数
unsigned char RxComplete = 0; //接收完成标志
unsigned char UART_RxData[20]; //接收字符串
unsigned char TubeDispCmd[3]; //数码管显示命令
/**
***************************************************************************************
* 函 数:串口发送单个字符函数
* 参 数:chr:发送的单个字符
* 返回值:无
***************************************************************************************
*/
void UART_SendChar(char chr) //串口发送单个字符函数
{
SBUF = chr; //串口发送单个字符
while(!TI); //等待发送完成
TI = 0; //清除发送标志
}
/**
***************************************************************************************
* 函 数:串口发送字符串函数
* 参 数:str:指向字符串首字符的指针
* 返回值:无
***************************************************************************************
*/
void UART_SendString(char *str) //串口发送字符串函数
{
while(*str!='\0')
{
SBUF = *str; //串口发送单个字符
while(!TI); //等待发送完成
TI = 0; //清除发送标志
str++; //指向下一个字符
}
}
/**
***************************************************************************************
* 函 数:串口发送整型int(4)函数
* 参 数:intNum:需发送的int(4)型变量
* 范 围:int(4):-2147483648 ~ 2147483647
* 返回值:无
***************************************************************************************
*/
void UART_SendInt(int intNum) //串口发送整型int(4)函数
{
unsigned char i; //计数变量,0~255
unsigned char n=0; //intNum位数,最多10位
char intStr[10]; //int(4)型变量最多10个数字字符
if(intNum<0) //intNum<0
{
UART_SendChar('-'); //先发送负号'-'
intNum *= -1; //intNum取绝对值
}
do{
intStr[n] = intNum%10+48; //获取intNum各位字符
intNum /= 10;
n++; //字符个数加1
}while(intNum>0);
for(i=0;i