资源简介
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
SDA=1; /*发送起始条件的数据信号*/
_nop_();
SCL=1;
delay_5us(); //起始条件建立时间大于4.7us
SDA=0; //发送起始信号
delay_5us(); //起始条件锁定时间大于4us
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
delay_2us();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SDA=0; //发送结束条件的数据信号
delay_2us();
SCL=1; //发送结束条件的时钟信号
delay_5us(); //结束条件建立时间大于4μ
SDA=1; /*发送I2C总线结束信号*/
delay_5us();
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{ uchar BitCnt,count;
for(BitCnt=0;BitCnt<8;BitCnt ) /*要传送的数据长度为8位*/
{
if(c&0x80)SDA=1; /*判断发送位*/
else SDA=0;
delay_2us();
SCL=1; //置时钟线为高,通知被控器开始接收数据位
delay_5us(); //保证时钟高电平周期大于4us
SCL=0;
c=c<<1;
}
_nop_();
_nop_();
SDA=1; /*8位发送完后释放数据线,准备接收应答位*/
delay_5us();
delay_5us(); //为了在示波器上更好看出应答时钟,多增加一个延时, 间隔大一点
SCL=1;
_nop_();
_nop_();
/*********************************************************************************************
由于BQ500414Q工作很忙,应答太慢,动态的不准时,所以做这个保证应答时钟是有效的。如果从端BQ500414Q还
没有应答时,但此时主控MCU把SCL置高了,此时BQ500414Q会拉强行把SCL拉低,一直要到BQ500414Q发出的SDA
应答是有效时,BQ500414Q才会放开对SCL的拉低。这是BQ500414Q与EEPROM的I2C一个差大的差别。
*********************************************************************************************/
for(count=0;count<100;count ) //等待从端从BUSY状态恢复出来, 放开SCL才能置高.此循环最大延时110uS.
{ if(SCL==1)
break;
_nop_();
}
delay_2us(); //应答高电平>=4us
delay_2us();
if(SDA==1)ack=0; /*判断是否接收到应答信号*/
else ack=1;
SCL=0;
delay_5us();
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte()
{
uchar retc=0,BitCnt,count;
SDA=1;
delay_5us(); //由于BQ500414Q芯片工作很忙, 延时
for(BitCnt=0;BitCnt<8;BitCnt )
{
SCL=0;
delay_5us(); /*时钟低电平周期大于4.7μs*/
SCL=1;
_nop_();
_nop_();
/*********************************************************************************************
由于BQ***工作很忙,发出数据太慢,动态的不准时,时快时慢。处理完1字节后,有时要大于50us才发下一个字节.
如果从端BQ500414Q还没有发出有效的数据,但此时主控MCU把SCL置高了,此时BQ500414Q会拉强行把SCL拉低,
直要到BQ500414Q发出的SDA是有效时,BQ500414Q才会放开对SCL的拉低。这是BQ500414Q与EEPROM的I2C一个差大的差别。
*********************************************************************************************/
for(count=0;count<100;count ) //等待从端由BUSY状态恢复出来, 放开SCL才能置高.此循环最大延时110mS.
{
if(SCL==1)
break;
_nop_();
}
delay_2us();
retc=retc<<1;
if(SDA==1)retc=retc | 1;
_nop_();
}
SCL=0;
_nop_();
_nop_();
return(retc);
}
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0;
else SDA=1;
delay_5us();
SCL=1;
delay_5us();
SCL=0;
delay_5us();
}
/*******************************************************************
用户接口函数
*******************************************************************/
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
uchar ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
if(no == 0)
return(1);
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
for(i=0;i<no;i )
{
SendByte(*s);
if(ack==0)return(0);
s ;
}
Stop_I2c();
return(1);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit RecndStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
Start_I2c();
SendByte(sla 1);
if(ack==0)return(0);
for(i=0;i<no-1;i )
{
*s=RcvByte();
Ack_I2c(0);
s ;
}
*s=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(1);
}
uint8 led_state=0;
static uchar buffer_pld_monitor[32]; //PLD_MONITOR (Read only – Command 0xD5 ),读数据存放
static uchar buffer_tx_state[32]; //TX_STATS (Read only – Command 0xD1)),读数据存放
uchar COMM_GetTestvolt()
{
uchar ret;
ret = volt_test;
volt_test = 0;
return ret;
}
uchar COMM_GetTestamp()
{
uchar ret;
ret = amp_test;
amp_test = 0;
return ret;
}
uchar COMM_GetTestfod()
{
uchar ret;
ret = fod_test;
fod_test = 0;
return ret;
}
uchar COMM_GetTestpld()
{
uchar ret;
ret = pld_test;
pld_test = 0;
return ret;
}
uchar COMM_GetTestsend_power()
{
uchar ret;
ret = send_power_test;
send_power_test = 0;
return ret;
}
uchar COMM_GetTestrecv_power()
{
uchar ret;
ret = recv_power_test;
recv_power_test = 0;
return ret;
}
uchar COMM_GetTestvol_det1()
{
uchar ret;
ret = vol_det1_test;
vol_det1_test = 0;
return ret;
}
uchar COMM_GetTestvol_det2()
{
uchar ret;
ret = vol_det2_test;
vol_det2_test = 0;
return ret;
}
void ChargeCtrl_Main()
{
led_state=buffer_tx_state[22];
switch(ch_state)
{
case eIDLE:
if(led_state == LED_STATE_PWR_TRANS||led_state == LED_STATE_PWR_CPLT)
{
ch_state=eSTARTED;
charge_flag=1;
}
else
{
;//do nothing
}
break;
case eSTARTED:
charge_flag=1;
if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eCHARING;
charge_flag=2;
}
if(led_state == LED_STATE_PWR_CPLT)
{
ch_state=eFULL;
charge_flag=3;
}
if(led_state == LED_STATE_STANDBY)
{
ch_state=eREMOVE;
charge_flag=4;
}
break;
case eCHARING:
ch_state=2;
if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eCHARING;
charge_flag=2;
}
else if(led_state == LED_STATE_PWR_CPLT)
{
ch_state=eFULL;
charge_flag=3;
}
else if((led_state == LED_STATE_STANDBY))
{
ch_state=eREMOVE;
charge_flag=4;
}
break;
case eFULL:
ch_state=3;
if(led_state == LED_STATE_STANDBY)
{
ch_state=eREMOVE;
charge_flag=4;
}
else if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eSTARTED;
charge_flag=1;
}
break;
default:
break;
}
}
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
SDA=1; /*发送起始条件的数据信号*/
_nop_();
SCL=1;
delay_5us(); //起始条件建立时间大于4.7us
SDA=0; //发送起始信号
delay_5us(); //起始条件锁定时间大于4us
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
delay_2us();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SDA=0; //发送结束条件的数据信号
delay_2us();
SCL=1; //发送结束条件的时钟信号
delay_5us(); //结束条件建立时间大于4μ
SDA=1; /*发送I2C总线结束信号*/
delay_5us();
}
/*******************************************************************
字节数据发送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{ uchar BitCnt,count;
for(BitCnt=0;BitCnt<8;BitCnt ) /*要传送的数据长度为8位*/
{
if(c&0x80)SDA=1; /*判断发送位*/
else SDA=0;
delay_2us();
SCL=1; //置时钟线为高,通知被控器开始接收数据位
delay_5us(); //保证时钟高电平周期大于4us
SCL=0;
c=c<<1;
}
_nop_();
_nop_();
SDA=1; /*8位发送完后释放数据线,准备接收应答位*/
delay_5us();
delay_5us(); //为了在示波器上更好看出应答时钟,多增加一个延时, 间隔大一点
SCL=1;
_nop_();
_nop_();
/*********************************************************************************************
由于BQ500414Q工作很忙,应答太慢,动态的不准时,所以做这个保证应答时钟是有效的。如果从端BQ500414Q还
没有应答时,但此时主控MCU把SCL置高了,此时BQ500414Q会拉强行把SCL拉低,一直要到BQ500414Q发出的SDA
应答是有效时,BQ500414Q才会放开对SCL的拉低。这是BQ500414Q与EEPROM的I2C一个差大的差别。
*********************************************************************************************/
for(count=0;count<100;count ) //等待从端从BUSY状态恢复出来, 放开SCL才能置高.此循环最大延时110uS.
{ if(SCL==1)
break;
_nop_();
}
delay_2us(); //应答高电平>=4us
delay_2us();
if(SDA==1)ack=0; /*判断是否接收到应答信号*/
else ack=1;
SCL=0;
delay_5us();
}
/*******************************************************************
字节数据接收函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte()
{
uchar retc=0,BitCnt,count;
SDA=1;
delay_5us(); //由于BQ500414Q芯片工作很忙, 延时
for(BitCnt=0;BitCnt<8;BitCnt )
{
SCL=0;
delay_5us(); /*时钟低电平周期大于4.7μs*/
SCL=1;
_nop_();
_nop_();
/*********************************************************************************************
由于BQ***工作很忙,发出数据太慢,动态的不准时,时快时慢。处理完1字节后,有时要大于50us才发下一个字节.
如果从端BQ500414Q还没有发出有效的数据,但此时主控MCU把SCL置高了,此时BQ500414Q会拉强行把SCL拉低,
直要到BQ500414Q发出的SDA是有效时,BQ500414Q才会放开对SCL的拉低。这是BQ500414Q与EEPROM的I2C一个差大的差别。
*********************************************************************************************/
for(count=0;count<100;count ) //等待从端由BUSY状态恢复出来, 放开SCL才能置高.此循环最大延时110mS.
{
if(SCL==1)
break;
_nop_();
}
delay_2us();
retc=retc<<1;
if(SDA==1)retc=retc | 1;
_nop_();
}
SCL=0;
_nop_();
_nop_();
return(retc);
}
/********************************************************************
应答子函数
函数原型: void Ack_I2c(bit a);
功能: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0;
else SDA=1;
delay_5us();
SCL=1;
delay_5us();
SCL=0;
delay_5us();
}
/*******************************************************************
用户接口函数
*******************************************************************/
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
uchar ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{ uchar i;
if(no == 0)
return(1);
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
for(i=0;i<no;i )
{
SendByte(*s);
if(ack==0)return(0);
s ;
}
Stop_I2c();
return(1);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: bit RecndStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c();
SendByte(sla);
if(ack==0)return(0);
SendByte(suba);
if(ack==0)return(0);
Start_I2c();
SendByte(sla 1);
if(ack==0)return(0);
for(i=0;i<no-1;i )
{
*s=RcvByte();
Ack_I2c(0);
s ;
}
*s=RcvByte();
Ack_I2c(1);
Stop_I2c();
return(1);
}
uint8 led_state=0;
static uchar buffer_pld_monitor[32]; //PLD_MONITOR (Read only – Command 0xD5 ),读数据存放
static uchar buffer_tx_state[32]; //TX_STATS (Read only – Command 0xD1)),读数据存放
uchar COMM_GetTestvolt()
{
uchar ret;
ret = volt_test;
volt_test = 0;
return ret;
}
uchar COMM_GetTestamp()
{
uchar ret;
ret = amp_test;
amp_test = 0;
return ret;
}
uchar COMM_GetTestfod()
{
uchar ret;
ret = fod_test;
fod_test = 0;
return ret;
}
uchar COMM_GetTestpld()
{
uchar ret;
ret = pld_test;
pld_test = 0;
return ret;
}
uchar COMM_GetTestsend_power()
{
uchar ret;
ret = send_power_test;
send_power_test = 0;
return ret;
}
uchar COMM_GetTestrecv_power()
{
uchar ret;
ret = recv_power_test;
recv_power_test = 0;
return ret;
}
uchar COMM_GetTestvol_det1()
{
uchar ret;
ret = vol_det1_test;
vol_det1_test = 0;
return ret;
}
uchar COMM_GetTestvol_det2()
{
uchar ret;
ret = vol_det2_test;
vol_det2_test = 0;
return ret;
}
void ChargeCtrl_Main()
{
led_state=buffer_tx_state[22];
switch(ch_state)
{
case eIDLE:
if(led_state == LED_STATE_PWR_TRANS||led_state == LED_STATE_PWR_CPLT)
{
ch_state=eSTARTED;
charge_flag=1;
}
else
{
;//do nothing
}
break;
case eSTARTED:
charge_flag=1;
if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eCHARING;
charge_flag=2;
}
if(led_state == LED_STATE_PWR_CPLT)
{
ch_state=eFULL;
charge_flag=3;
}
if(led_state == LED_STATE_STANDBY)
{
ch_state=eREMOVE;
charge_flag=4;
}
break;
case eCHARING:
ch_state=2;
if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eCHARING;
charge_flag=2;
}
else if(led_state == LED_STATE_PWR_CPLT)
{
ch_state=eFULL;
charge_flag=3;
}
else if((led_state == LED_STATE_STANDBY))
{
ch_state=eREMOVE;
charge_flag=4;
}
break;
case eFULL:
ch_state=3;
if(led_state == LED_STATE_STANDBY)
{
ch_state=eREMOVE;
charge_flag=4;
}
else if(led_state == LED_STATE_PWR_TRANS)
{
ch_state=eSTARTED;
charge_flag=1;
}
break;
default:
break;
}
}
代码片段和文件信息
#include “main(st).h“
#include “adc.h“
#define ADC_CH_NUM 3U
#define ADC_BUF_SIZE 8U
typedef struct
{
uint8 np; /*buf point*/
uint8 nBufNum; /*num of valid data*/
uint16 nBufArray[ADC_BUF_SIZE];
}ADC_Buf_t;
static ADC_Buf_t ADC_Buf[ADC_CH_NUM];
/*----------------------------
Get ADC result
----------------------------*/
uint16 GetADCResult(BYTE ch)
{
uint16 adc_result=0;
ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ch | ADC_START;
_nop_(); //Must wait before inquiry
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
ADC_CONTR &= ~ADC_FLAG; //Close ADC
adc_result = ADC_RES;
adc_result = adc_result<<2;
adc_result|=(ADC_LOW2&0x03);
return adc_result; //Return ADC result
}
/*----------------------------
Software delay function
----------------------------*/
void Delay(WORD n)
{
WORD x;
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 7278 2017-01-09 19:07 stc_I2C_pro\output\adc.lst
文件 16752 2017-01-09 19:07 stc_I2C_pro\output\adc.obj
文件 12111 2017-01-09 19:07 stc_I2C_pro\output\app_Communct.lst
文件 24708 2017-01-09 19:07 stc_I2C_pro\output\app_Communct.obj
文件 20477 2017-01-09 19:07 stc_I2C_pro\output\cmpt_uart.lst
文件 39018 2017-01-09 19:07 stc_I2C_pro\output\cmpt_uart.obj
文件 2046 2017-01-09 19:07 stc_I2C_pro\output\delay.lst
文件 3060 2017-01-09 19:07 stc_I2C_pro\output\delay.obj
文件 2670 2017-01-09 19:07 stc_I2C_pro\output\driver_wrap.lst
文件 10039 2017-01-09 19:07 stc_I2C_pro\output\driver_wrap.obj
文件 26150 2017-01-09 19:07 stc_I2C_pro\output\iic.lst
文件 37481 2017-01-09 19:07 stc_I2C_pro\output\iic.obj
文件 2829 2017-01-09 19:07 stc_I2C_pro\output\interrupt.lst
文件 9916 2017-01-09 19:07 stc_I2C_pro\output\interrupt.obj
文件 10874 2017-01-09 19:07 stc_I2C_pro\output\lcd1602.lst
文件 24380 2017-01-09 19:07 stc_I2C_pro\output\lcd1602.obj
文件 17241 2017-01-09 19:07 stc_I2C_pro\output\main(ST).lst
文件 23915 2017-01-09 19:07 stc_I2C_pro\output\main(ST).obj
文件 15116 2017-01-09 19:07 stc_I2C_pro\output\STARTUP.lst
文件 1062 2017-01-09 19:07 stc_I2C_pro\output\STARTUP.obj
文件 203339 2017-01-09 19:07 stc_I2C_pro\output\stc_pro
文件 2829 2016-06-24 18:48 stc_I2C_pro\output\stc_pro.build_log.htm
文件 24105 2017-01-09 19:07 stc_I2C_pro\output\stc_pro.hex
文件 58014 2016-06-15 13:53 stc_I2C_pro\output\stc_pro.LIB
文件 368 2017-01-09 19:07 stc_I2C_pro\output\stc_pro.lnp
文件 221510 2017-01-09 19:07 stc_I2C_pro\output\stc_pro.map
文件 175 2017-04-13 10:43 stc_I2C_pro\output\stc_pro.plg
文件 126779 2017-01-09 19:07 stc_I2C_pro\output\stc_pro.SBR
文件 304 2016-06-15 13:53 stc_I2C_pro\output\stc_pro.__b
文件 5094 2017-01-09 19:07 stc_I2C_pro\output\timer.lst
............此处省略80个文件信息
相关资源
- 利用C生成正弦波DA数据
- stc15w单片机mpr121触摸按键
- 51单片机:信号发生器
- stc系列单片机串口通讯
- qt5 旋转(.patch文件源码)
- 3G系统-WCDMA和CDMA2000完整MATLAB仿真程序
- 非阻塞式AT指令发送接收工程,可驱动
- RS485;PC到单片机单向通讯;
- 加权调度算法(C语言)
- 单片机最小系统(附原理图和PCB).
- 超声波测距(LCD1602显示)
- 2017年电赛瑞萨芯片RX23T原理图.SchDoc
- FDCAN实验(CAN总线的使用)
- CS5532 的 STM32 驱动程序
- LCD12864显示屏使用手册和(串行方式、
- 80C51 family programmer guide
- C876模板(基于战舰STM32F103开发板)
- 蓝牙小车(BluetoothCar)
- STC15F单片机制作的:计算器、万年历
- 基于GEC6818开发板的电子相册
- STC51 ADC 采集及串口通讯
- STC15F104E单片机18B20温度传感器的
- 单片机串口通信(方式1)
- Unified Diagnostics Service (UDS) and OBD-
- An implementation of the ISO-TP (ISO15765-2)
- STM32F0硬件IIC
- CS5460A电量计量芯片应用程序
- STC15开发手持点巡检考勤机
- 灯珠内带驱动IC 的彩灯条控制!
- 基于PIC24单片机的AD7616程序
评论
共有 条评论