以下为.h文件:
#ifndef __TM1650_I2C_H
#define __TM1650_I2C_H
#include "stm8s.h"
#include "stm8s_gpio.h"
#include "tim1.h"
#include "usart2.h"
#include #include /********************************** TM1650芯片控制20路灯函数 PB7为SCL口 PB6为SDA口 **********************************/ #define SCL_TM1650 PC_ODR_ODR7 #define SDA_TM1650 PC_ODR_ODR6 #define SDAM_TM1650 PC_IDR_IDR6 #define SET_SCL_OUT_TM1650() {PC_DDR_DDR7=1; PC_CR1_C17 = 1; PC_CR2_C27 = 0;} #define SET_SDA_OUT_TM1650() {PC_DDR_DDR6=1; PC_CR1_C16 = 1; PC_CR2_C26 = 0;} #define SET_SDA_IN_TM1650() {PC_DDR_DDR6=0; PC_CR1_C16 = 0; PC_CR2_C26 = 0;} void IIC_Init_TM1650(void); void TDelay_us(u8 z); void I2C_Start_TM1650(void); void I2C_Stop_TM1650(void); void IIC_Ack_TM1650(void); void IIC_NAck_TM1650(void); uint8_t IIC_Wait_Ack_TM1650(void); void IIC_WrByte_TM1650(uint8_t txd); //u8 Scan_Key(void); void TM1650_Set(u8 add,u8 dat); void Init_Tm1650(void); #endif 以下为.c文件: #include "TM1650_I2C.h" //-------------------------------------------------------------- // Prototype : void IIC_Init_TM1650(void) // Calls : // Description : //-------------------------------------------------------------- void IIC_Init_TM1650(void) { SET_SCL_OUT_TM1650(); SET_SDA_OUT_TM1650(); SCL_TM1650 = 1; SDA_TM1650 = 1; } //-------------------------------------------------------------- // Prototype : void Delay_us(void) // Description : 大约延时 z us //-------------------------------------------------------------- void TDelay_us(u8 z) { //u8 i; //fcpu 8MHz 时 //for (i=50; i>0; i--); while(z--) { nop();nop();nop();nop(); } } //-------------------------------------------------------------- // Prototype : void I2C_Start(void) // Calls : Delay_5us() // Description : Start Singnal //-------------------------------------------------------------- void I2C_Start_TM1650(void) { // SDA 1->0 while SCL High //SCL高电平期间,SDA出现一个下降沿表示起始信号 SET_SDA_OUT_TM1650(); SDA_TM1650 = 1; //数据线先保持为高,起始信号要该口的下降沿 TDelay_us(4); SCL_TM1650 = 1; //时钟线保持为高 TDelay_us(40); //有一个大概5us的延时具体以器件而定 SDA_TM1650 = 0; //数据线拉低出现下降沿 TDelay_us(4); //延时 一小会,保证可靠的下降沿 SCL_TM1650 = 0; //拉低时钟线,保证接下来数据线允许改变 } //-------------------------------------------------------------- // Prototype : void I2C_Stop(void) // Calls : Delay_5us() // Description : Stop Singnal //-------------------------------------------------------------- void I2C_Stop_TM1650(void) { // SDA 0->1 while SCL High //SCL高电平期间,SDA产生一个上升沿 表示停止 SET_SDA_OUT_TM1650(); SCL_TM1650 = 0; TDelay_us(2); SDA_TM1650 = 0; //保证数据线为低电平 TDelay_us(40); SCL_TM1650 = 1; //先保证时钟线为高电平 TDelay_us(10); //延时 以得到一个可靠的电平信号 SDA_TM1650 = 1; //数据线出现上升沿 TDelay_us(40); //延时 保证一个可靠的高电平 } //应答函数 void IIC_Ack_TM1650(void) { //数据线一直保持为低电平,时钟线出现上升沿即为应答 SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 0; TDelay_us(10); SCL_TM1650 = 0; TDelay_us(40); SCL_TM1650 = 1; TDelay_us(40); //应答完成后 将时钟线拉低 允许数据修改 SCL_TM1650 = 0; } //非应答 void IIC_NAck_TM1650(void) { //非应答即相反 与应答区别即为数据线保持高电平即可 SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 1; TDelay_us(10); SCL_TM1650 = 0; TDelay_us(40); SCL_TM1650 = 1; TDelay_us(40); //最后要将时钟线拉低 允许数据变化 SCL_TM1650 = 0; } //等待应答 uint8_t IIC_Wait_Ack_TM1650(void)//0为有应答,1为无应答 { //应答等待计数 uint8_t ackTime = 0; //先将数据线要设置成输入模式本程序未体现,有应答则会出现下降沿 SCL_TM1650 = 0; SET_SDA_OUT_TM1650(); TDelay_us(10); SDA_TM1650 = 1;// TDelay_us(30); SET_SDA_IN_TM1650();//切换为输入模式 //时钟线拉高 SCL_TM1650 = 1; TDelay_us(30); //等待数据线拉低应答 while(SDAM_TM1650){ //如果在该时间内仍未拉低 ackTime ++; if(ackTime > 250) { //认为非应答 停止信号 I2C_Stop_TM1650(); return 1; } } SCL_TM1650 = 0; return 0 ; } void IIC_WrByte_TM1650(uint8_t txd) { //定义一个计数变量 uint8_t i; SET_SDA_OUT_TM1650(); //将时钟线拉低允许数据改变 // SCL = 0; //按位发送数据 for(i = 0;i < 8; i ++) { TDelay_us(2); if((txd&0x80)>>7) //0x80 1000 0000 SDA_TM1650=1; else SDA_TM1650=0; txd<<=1; TDelay_us(20); SCL_TM1650=1; TDelay_us(20); SCL_TM1650=0; TDelay_us(20); } } /*************************** u8 Scan_Key(void) //按键扫描 { u8 i; u8 rekey; I2C_Start_TM1650(); IIC_WrByte_TM1650(0x49);//读按键命令 IIC_Ack_TM1650(); //DIO_H; SET_SDA_IN_TM1650();//切换为输入模式 for(i=0;i<8;i++) { SCL_TM1650=1; rekey = rekey<<1; if(SDAM_TM1650) { rekey++; } TDelay_us(5); SCL_TM1650=0; } IIC_Ack_TM1650(); I2C_Stop_TM1650(); return(rekey); } ****************************/ void TM1650_Set(u8 add,u8 dat) //数码管显示 { //写显存必须从高地址开始写 I2C_Start_TM1650(); IIC_WrByte_TM1650(add); //第一个显存地址 IIC_Ack_TM1650(); IIC_WrByte_TM1650(dat); IIC_Ack_TM1650(); I2C_Stop_TM1650(); } void Init_Tm1650(void) { IIC_Init_TM1650(); delay_ms(50); //需要延时一小段时间,否则开显示会无响应 TM1650_Set(0x48,0x31);//初始化为5级灰度,开显示 } 注意:TM1650芯片启动可能需要一点时间,故发送开显示前应延时一小段时间,否则会收不到。
上一篇:STM8S103K3 I2C
下一篇:STM8S MAX7219点阵模块驱动芯片程序
推荐阅读最新更新时间:2024-11-22 14:31
设计资源 培训 开发板 精华推荐
- 基于EG3013的H桥四路电机驱动板
- LT8304ES8E 4V 至 100Vin、140Vout 升压转换器的典型应用电路
- KSZ8462HLI-EVAL,评估板为支持 KSZ8462HL IEEE 1588 精确时间协议 (PTP) 的交换机产品提供平台
- 时钟控制/2相双极型步进电机驱动IC —— TB67S109AFTG
- MCP1630RD-LIC1、MCP1630 锂离子多槽电池充电器参考设计
- Demo
- 用于 NPN 输出电流升压器的 AD584 引脚可编程精密电压基准的典型应用
- 萝丽6通接收器
- MC32PF3000A1EP PMIC 解决方案电源管理的典型应用
- EVAL-AD7490SDZ,用于评估 AD7490 逐次逼近型 ADC 的评估板
- 泰克有奖看视频 深入浅出剖析高速信号的抖动和眼图
- 我是大侦探之:寻找遗落的TI电源拼图
- 索取海报:泰克矢量网络分析仪基础知识
- 报名直播赢【手环、摄像头、雨伞、手机支架】罗德与施瓦茨USB 3.2一致性测试
- 【MPS有奖分享】便携式多功能电工台的核“芯”功能测试与结构设计
- 你们想要的XMC4800 Relax EtherCAT Kit来了,速度来申请!
- 工程师快乐,所以行业记者快乐!
- 有奖直播:英飞凌 MERUS™ D 类音频放大器的多电平技术及其优势
- 有奖直播:低功耗、小尺寸&高温环境、带触摸功能——瑞萨电子最新16位RL78/G系列单片机介绍
- 【社区大讲堂】ARM+DSP双核处理器应用程序开发