目录
背景
我们在单片机开发过程中,经常需要通过IO口来模拟通信接口(I2C、两线串行接口).
通过本篇文章,IO模拟两线串行接口,举一反三,来达到模拟其他通信接口的能力。
TM1640是一种LED(发光二极管显示器)驱动控制专用电路。STM32通过两线串行接口和
TM1640通信。
发送时序说明
1)空闲的时候,DIN和SCLK 都为高
2)DIN 先拉低,SCLK再拉低,表示数据开始发送
3)在SCLK 为低电平的时候,DIN信号才可以改变
4)DIN 写入数据之后,SCLK要拉高
5)当8位数据传完之后,SCLK和DIN都保持为低。
6)SCLK为高,DIN由低变高说明传输数据结束
#define TM1640_GPIOPORT GPIOA //定义IO接口
#define TM1640_DIN GPIO_Pin_12 //定义IO接口
#define TM1640_SCLK GPIO_Pin_11 //定义IO接口
#define TM1640_LEDPORT 0xC8 //定义IO接口
void TM1640_Init(void){ //TM1640接口初始化
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = TM1640_DIN | TM1640_SCLK; //选择端口号(0~15或all)
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)
GPIO_Init(TM1640_GPIOPORT, &GPIO_InitStructure);
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1
TM1640_start();
TM1640_write(TM1640MEDO_ADD); //设置数据,0x40,0x44分别对应地址自动加一和固定地址模式
TM1640_stop();
TM1640_start();
TM1640_write(TM1640MEDO_DISPLAY); //控制显示,开显示,0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f分别对应脉冲宽度为:
//------------------1/16, 2/16, 4/16, 10/16, 11/16, 12/16, 13/16, 14/16 //0x80关显示
TM1640_stop();
}
准备开始发送
void TM1640_start(){ //通信时序 启始(基础GPIO操作)(低层)
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1
delay_us(DEL);
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0
delay_us(DEL);
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0
delay_us(DEL);
}
发送数据
void TM1640_write(u8 date){ //写数据(低层)
u8 i;
u8 aa;
aa=date;
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0
for(i=0;i<8;i++){
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0
delay_us(DEL);
if(aa&0x01){
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1
delay_us(DEL);
}else{
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0
delay_us(DEL);
}
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1
delay_us(DEL);
aa=aa>>1;
}
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0)); //接口输出0
}
结束数据发送
void TM1640_stop(){ //通信时序 结束(基础GPIO操作)(低层)
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0)); //接口输出0
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1
delay_us(DEL);
GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1
delay_us(DEL);
}