資源簡介
/*******************************************************************
起動總線函數
函數原型: 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個文件信息
評論
共有 條評論