嵌入式驱动程序(5-3)点灯大师③之TM1650
作为一个嵌入式工程师,“点灯”是必备技能,哈哈哈(手动斜眼笑),除了普通IO口可以控制led灯亮灭之外,还有很多驱动ic,只需要2或3根IO线就可以控制几十盏灯。所以会出一系列“点灯”文章。励志成为一个“点灯”大师。
点灯大师③之TM1650
1. 资料
TM1650.pdf提取码:gik3
2. 基本知识点
- 两线接口(CLK,DIO)
3. 函数功能
/
//从TM1650读取一个字节
unsigned char TM1650_ReadOneByte(TM1650_CONFIG_t tm)
{
unsigned char i;
unsigned char data=0;
//DAT设置成输入
tm.DAT_SET_INPUT();
_Delay_(1);
//拉高时钟信号
tm.CLK_IO_HIGH();
_Delay_(1);
for(i = 0;i<8;i++)
{
data <<= 1;
//拉低时钟,下降沿读取信号
tm.CLK_IO_LOW();
_Delay_(1);
if(tm.DAT_STA())
{
//高电平
data++;
}
_Delay_(1);
tm.CLK_IO_HIGH();
_Delay_(1);
}
_Delay_(1);
_Delay_(1);
_Delay_(1);
_Delay_(1);
return data;
}
/
//向TM1650写入一个字节
void TM1650_WriteOneByte(TM1650_CONFIG_t tm, unsigned char dat)
{
unsigned char i;
//DAT设置成输出
tm.DAT_SET_OUTPUT();
_Delay_(1);
//拉低时钟信号
tm.CLK_IO_LOW();
_Delay_(1);
for(i=0; i < 8; i++)
{
if(dat & 0x80)
tm.DAT_IO_HIGH();
else
tm.DAT_IO_LOW();
_Delay_(1);
tm.CLK_IO_HIGH();
_Delay_(1);
tm.CLK_IO_LOW();
_Delay_(1);
dat <<= 1;
}
_Delay_(1);
_Delay_(1);
}
/
//开始信号
void TM1650_Start(TM1650_CONFIG_t tm)
{
//DAT设置成输出
tm.DAT_SET_OUTPUT();
//数据脚高电平
tm.DAT_IO_HIGH();_Delay_(1);
//时钟脚高电平
tm.CLK_IO_HIGH();_Delay_(1);
//时钟脚为高电平时,数据脚拉低表示IIC启动
tm.DAT_IO_LOW();_Delay_(1);
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
}
/
//结束信号
void TM1650_Stop(TM1650_CONFIG_t tm)
{
//DAT设置成输出
tm.DAT_SET_OUTPUT();
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
//数据脚低电平
tm.DAT_IO_LOW();_Delay_(1);
//时钟脚高电平
tm.CLK_IO_HIGH();_Delay_(1);
//时钟脚为高电平时,数据脚拉高表示IIC停止
tm.DAT_IO_HIGH();_Delay_(1);
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
}
/
//等待应答
void TM1650_WaitAck(TM1650_CONFIG_t tm)
{
unsigned char temp = 0;
//DAT设置成输入
tm.DAT_SET_INPUT();
//等待应答
do{
temp++;
}while(temp<200 && tm.DAT_STA());
//时钟脚高电平
tm.CLK_IO_HIGH();_Delay_(1);
_Delay_(1);
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
_Delay_(1);
}
/
//应答信号
void TM650_Ack(TM1650_CONFIG_t tm)
{
//数据脚设置成输出模式
tm.DAT_SET_OUTPUT();
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
//数据脚低电平
tm.DAT_IO_LOW();_Delay_(1);
//时钟脚高电平
tm.CLK_IO_HIGH();_Delay_(1);
//时钟脚低电平
tm.CLK_IO_LOW();_Delay_(1);
}
/
//向TM1650写入命令
void TM1650_WriteCommand(TM1650_CONFIG_t tm, unsigned char comm)
{
//开始信号
TM1650_Start(tm);
//写指令
TM1650_WriteOneByte(tm,0x48);
//等待应答
TM1650_WaitAck(tm);
//写指令
TM1650_WriteOneByte(tm,comm);
//等待应答
TM1650_WaitAck(tm);
//结束信号
TM1650_Stop(tm);
}
/
//向TM1650写入显示
void TM1650_Display(TM1650_CONFIG_t tm, unsigned char* data)
{
unsigned char i=0;
for(i=0;i<4;i++)
{
//开始信号
TM1650_Start(tm);
//写地址
TM1650_WriteOneByte(tm,0x68+2*i);
//等待应答
TM1650_WaitAck(tm);
//写数据
TM1650_WriteOneByte(tm,*(data+i));
//等待应答
TM1650_WaitAck(tm);
//结束信号
TM1650_Stop(tm);
}
}
/
//向TM1650读键值
unsigned char TM1650_KeyScan(TM1650_CONFIG_t tm)
{
unsigned char data =0 ;
//开始信号
TM1650_Start(tm);
//写指令
TM1650_WriteOneByte(tm,0x49);
//等待应答
TM1650_WaitAck(tm);
//读键值
data = TM1650_ReadOneByte(tm);
TM650_Ack(tm);
//结束信号
TM1650_Stop(tm);
return data;
}
/
//TM1650轮询处理
void TM1650_process(void)
{
unsigned char i;
//设置8级亮度,8段显示
TM1650_WriteCommand(tm1650, PULSE_08_8|B3_8S_4G|B0_DISP_ON);
//全亮
for(i=0;i<4;i++)
drv_tm1650_buf[i] = 0xff;
//全灭
for(i=0;i<4;i++)
drv_tm1650_buf[i] = 0x00;
TM1650_Display(tm1650, drv_tm1650_buf);
//读取键值
key_tm1650_value = TM1650_KeyScan(tm1650);
}
void TM1650_init(void)
{
}
4. 说明
- 代码仅供参考。
5. 代码下载
TM1650代码提取码:vjnq
我的个人博客网址:一个点的频率 希望大家关注一下,谢谢!!!
版权声明:本文为weixin_49467863原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。