当前位置:网站首页>采用中微BATG135实现IIC数据/指令交互
采用中微BATG135实现IIC数据/指令交互
2022-07-04 06:19:00 【喜欢吃火锅的泪】
本例程是一次项目中使用到IIC实现3台中微直接的数据交互,而中微给出的IIC例程偏向简单,实现中遇到很多问题,要真正实现IIC,需要进行改写。
首先需要进行中微作为从机的初始化:
void IICA0_Init(void)
{
CGC->PER0 |= CGC_PER0_IICA0EN_Msk; /* enables input clock supply */
IICA->IICCTL00 = _00_IICA_OPERATION_STOP; /* stop operation */
INTC_DisableIRQ(IICA_IRQn); /* disable INTIICA interrupt flag */
INTC_ClearPendingIRQ(IICA_IRQn); /* clear INTIICA interrupt flag */#ifdef IICA_STANDARD_MODE /* Max rate: 100Kbps */
IICA->IICCTL01 = _00_IICA_OPERATE_STANDARD; /* operates in standard mode */
IICA->IICWL0 = _4B_IICA_LOW_WIDTH;
IICA->IICWH0 = _53_IICA_HIGH_WIDTH;
#endif
#ifdef IICA_FAST_MODE /* Max rate: 400Kbps */
IICA->IICCTL01 = _08_IICA_OPERATE_FAST; /* operates in fast mode */
IICA->IICCTL01 |= _04_IICA_FILTER_ON; /* filter on */
IICA->IICWL0 = _14_IICA_LOW_WIDTH;
IICA->IICWH0 = _12_IICA_HIGH_WIDTH;
#endif
IICA->IICCTL01 |= _01_IICA_FCLK_2_SELECTED;
IICA->SVA0 = _98_IICA0_SLAVEADDRESS;
IICA->IICF0 |= _02_IICA_WITHOUT_DETECTION; /* enable generation of a start condition without detecting a stop
condition */
IICA->IICF0 |= _01_IICA_RESERVATION_DISABLE; /* disable communication reservation */
IICA->IICCTL00 |= _08_IICA_INTERRUPT_REQUEST_NINTH; /* interrupt request is generated at the ninth clock's falling edge */
IICA->IICCTL00 |= _00_IICA_ACKOWNLEDGMENT_DISABLE; /* enable acknowledgment */
IICA->IICCTL00 |= _80_IICA_OPERATION_ENABLE; /* enable operation */
IICA->IICCTL00 |= _40_IICA_OPERATION_STANDBY; /* this exits from the current communications and sets standby mode */
INTC_EnableIRQ(IICA_IRQn); /* enable INTIICA interrupt flag *//* Set SCLA0, SDAA0 pin */
SCLA0_PORT_SETTING();
SDAA0_PORT_SETTING();
}
其中:可根据中微的GPIO口进行IIC管脚映射
#define SCLA0_PORT_SETTING() do{ \
PORT->SCLA0PCFG = 0x13; /* allocate SCLA0 to P30 */ \
PORT->P3 &= ~(1 << 0); /* P30 output low level */ \
PORT->PM3 &= ~(1 << 0); /* P30 is N-ch open-drain output mode */ \
PORT->PMC3 &= ~(1 << 0); /* P30 digital function */ \
}while(0)/* ToDo: You can allocate the SDA00 to any desired pins with SDA00PCFG register */
#define SDAA0_PORT_SETTING() do{ \
PORT->SDAA0PCFG = 0x17; /* allocate SDAA0 to P50 */ \
PORT->P5 &= ~(1 << 0); /* P50 output low level */ \
PORT->PM5 &= ~(1 << 0); /* P50 is used as SDAA0 inout */ \
PORT->PMC5 &= ~(1 << 0); /* P50 digital function */ \
}while(0)
接下来是中微作为从机,实现数据的收发:
void IIC_Rec_Fuction(void)
{
static uint8_t times = 0;
static uint16_t interval = 0;
uint8_t csc = 0;
if (0 == times)
{
times = 1;
g_iica0_rx_len = 200;
g_iica0_rx_cnt = 0U;
g_iica0_rx_end = 0;
g_iica0_slave_status_flag = 0U;
IICA->IICA0 = SLVADDR_98U; /* slave address */
interval = gMillisecondTick;
}
if (1 == times)
{
if (((gMillisecondTick - interval) & 0xFFFF) > 10) //10ms
{
if ((g_iica0_rx_end == 1) && (RxBuffer2[0] == 0x55) && (RxBuffer2[1] == 0xAA) && (RxBuffer2[2] != 0x00))
{
for(uint16_t i = 0; i < (RxBuffer2[2] + 1);i++ )
{
csc ^= RxBuffer2[i];
}
if(csc == RxBuffer2[RxBuffer2[2] + 1])
{
Sys_Data.CmdData = (RxBuffer2[4]<<8) + RxBuffer2[5]; /*获取功能指令*/
memcpy(Sys_Data.Rec_Data,RxBuffer2,sizeof(RxBuffer2)); /*获取接收数据*/
//Sys_Data.Rec_Data为结构体数组:200个字节uint8_t Rec_Data[200]; /*接收数组*/,到此处代表接收的数据没有问题可进入
/*IIC接收函数处理中*/
Rev_Process_Fuction();
Send_Process_Connect_Upload(); /*IIC发送数据线程*/
g_iica0_rx_len = 200;
g_iica0_rx_cnt = 0U;
g_iica0_rx_end = 0;
g_iica0_slave_status_flag = 0U;
IICA->IICA0 = SLVADDR_98U; /* slave address */
}
}
interval = gMillisecondTick;
}
}else
{
g_iica0_rx_len = 200;
g_iica0_rx_cnt = 0U;
g_iica0_rx_end = 0;
g_iica0_slave_status_flag = 0U;
IICA->IICA0 = SLVADDR_98U; /* slave address */
}
}
其中:需要注意的是,要记得修改中微官方给的中断函数:
uint8_t RxBuffer2[200]; /*接收数组*/
uint16_t RxCounter2 = 0; /*接收计数*//***********************************************************************************************************************
* Function Name: iica0_slavehandler
* @brief This function is IICA0 slave handler.
* @param None
* @return None
***********************************************************************************************************************/
static void iica0_slavehandler(void)
{
/* Control for stop condition */
if (IICA->IICS0 & IICA_IICS0_SPD_Msk)
{
/* Get stop condition */
IICA->IICCTL00 &= ~IICA_IICCTL00_SPIE_Msk; /* SPIE0 = 0: disable */
if(g_iica0_slave_status_flag & _80_IICA_ADDRESS_COMPLETE)
{
if (g_iica0_slave_status_flag & 0x04U) /* send flag */
{
iica0_callback_slave_sendend();
}
if (g_iica0_slave_status_flag & 0x02U) /* receive flag */
{
iica0_callback_slave_receiveend();
}
}
g_iica0_slave_status_flag = 1U;
}
else
{
if ((g_iica0_slave_status_flag & _80_IICA_ADDRESS_COMPLETE) == 0U)
{
if (IICA->IICS0 & IICA_IICS0_COI_Msk)
{
IICA->IICCTL00 |= IICA_IICCTL00_SPIE_Msk; /* SPIE0 = 1: enable */
g_iica0_slave_status_flag = _80_IICA_ADDRESS_COMPLETE;if (IICA->IICS0 & IICA_IICS0_TRC_Msk) /* TRC0 == 1 */
{
IICA->IICCTL00 |= IICA_IICCTL00_WTIM_Msk; /* WTIM0 = 1: interrupt request is generated at the ninth clock's falling edge */if (g_iica0_tx_cnt > 0U)
{
IICA->IICA0 = *gp_iica0_tx_address;
gp_iica0_tx_address++;
g_iica0_tx_cnt--;
}
else
{
iica0_callback_slave_sendend();
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
}
}
else
{
IICA->IICCTL00 |= IICA_IICCTL00_ACKE_Msk; /* ACKE0 = 1U: enable acknowledgment */
IICA->IICCTL00 &= ~IICA_IICCTL00_WTIM_Msk; /* WTIM0 = 0U: interrupt request is generated at the eighth clock's falling edge */
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
}
}
else
{
iica0_callback_slave_error(MD_ERROR);
}
}
else
{
if (IICA->IICS0 & IICA_IICS0_TRC_Msk) /* TRC0 == 1 */
{
g_iica0_slave_status_flag |= 4U; /* send flag */
if ((0U == (IICA->IICS0 & IICA_IICS0_ACKD_Msk)) && (g_iica0_tx_cnt != 0U))
{
iica0_callback_slave_error(MD_NACK);
}
else
{
if (g_iica0_tx_cnt > 0U)
{
IICA->IICA0 = *gp_iica0_tx_address;
gp_iica0_tx_address++;
g_iica0_tx_cnt--;
}
else
{
iica0_callback_slave_sendend();
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
}
}
}
else
{
g_iica0_slave_status_flag |= 2U; /* receive flag */
if (g_iica0_rx_cnt < g_iica0_rx_len)
{
RxBuffer2[g_iica0_rx_cnt] = IICA->IICA0;
g_iica0_rx_cnt++;if (g_iica0_rx_cnt == g_iica0_rx_len)
{
IICA->IICCTL00 |= IICA_IICCTL00_WTIM_Msk; /* WTIM0 = 1: interrupt request is generated at the ninth clock's falling edge */
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
iica0_callback_slave_receiveend();
}
else
{
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
}
}
else
{
IICA->IICCTL00 |= IICA_IICCTL00_WREL_Msk; /* WREL0 = 1U: cancel wait */
}
}
}
}
}
/*
*********************************************************************************
* 函 数 名:Send_Process_Connect_Upload
* 功能说明:发送数据给蓝牙MCU
* 形 参:void
* 返 回 值:void
*********************************************************************************
*/
void Send_Process_Connect_Upload(void)
{
uint16_t value_size = 0;
//uint16_t i = 0;
//uint8_t tmpbuf[10]={0};
static uint8_t value[200] = {0};
/* 判断串口发送是否立即执行*/
if((Sys_Data.Com_Stas & COM_SEND_RDY) !=COM_SEND_RDY)
{
return;
}
/* 串口组包存值Value*/
// value_size = SendPacekData(Sys_Data.SendBuf,Sys_Data.SendLen,value);
IICA0_SlaveSend(SLVADDR_98U,value,value_size);
while(g_iica0_tx_end == 0);
#if 0
/*发送数据*/
printf_log("\r\n send_process :");
for(i=0;i<(value_size);i++)
{
memset(tmpbuf,0,10);
u8_T_array(value[i],tmpbuf);
printf_log((const char *)tmpbuf);
printf_log(" ");
}
printf_log("\r\n value_size = %d",value_size);
#endif
//Sys_Data.Com_Stas = 0; /*指令状态复位*/
// Sys_Data.CmdData = 0; /*指令复位*/
// Sys_Data.SendLen = 0; /*数据长度为0*/
// memset(Sys_Data.CmdPara,0,sizeof(Sys_Data.CmdPara)); /*命令数据包复位*/
}
边栏推荐
- Learn about the Internet of things protocol WiFi ZigBee Bluetooth, etc. --- WiFi and WiFi protocols start from WiFi. What do we need to know about WiFi protocol itself?
- MySQL information_ Schema database
- js如何将秒转换成时分秒显示
- STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
- 如何展开Collapse 的所有折叠面板
- After the festival, a large number of people change careers. Is it still time to be 30? Listen to the experience of the past people
- 对List进行排序工具类,可以对字符串排序
- APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?
- 746. Climb stairs with minimum cost
- Review | categories and mechanisms of action of covid-19 neutralizing antibodies and small molecule drugs
猜你喜欢

双色球案例

C language exercises (recursion)

R统计绘图-随机森林分类分析及物种丰度差异检验组合图

JS how to convert seconds into hours, minutes and seconds display
![Yiwen unlocks Huawei's new cloud skills - the whole process of aiot development [device access - ESP end-to-side data collection [mqtt]- real time data analysis] (step-by-step screenshot is more detai](/img/a5/be967170a18cb2de097f01a6d4e039.jpg)
Yiwen unlocks Huawei's new cloud skills - the whole process of aiot development [device access - ESP end-to-side data collection [mqtt]- real time data analysis] (step-by-step screenshot is more detai

How to solve the component conflicts caused by scrollbars in GridView

How to realize multi account login of video platform members

APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?

How to avoid JVM memory leakage?

AWT common components, FileDialog file selection box
随机推荐
MySQL installation and configuration
分布式CAP理论
The width of the picture in rich text used by wechat applet exceeds the problem
QT QTableWidget 表格列置顶需求的思路和代码
2022.7.3-----leetcode.556
[Chongqing Guangdong education] electronic circuit homework question bank of RTVU secondary school
如何避免 JVM 内存泄漏?
Kubernets first meeting
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
509. 斐波那契数、爬楼梯所有路径、爬楼梯最小花费
MySQL learning notes 3 - JDBC
[microservice] Nacos cluster building and loading file configuration
STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储
How to avoid JVM memory leakage?
Native Cloud - SSH articles must be read on Cloud (used for Remote Login to Cloud Server)
JSON Web Token----JWT和传统session登录认证对比
C realize Snake games
After the festival, a large number of people change careers. Is it still time to be 30? Listen to the experience of the past people
Nexus 6p从8.0降级6.0+root
C實現貪吃蛇小遊戲