当前位置:网站首页>采用中微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)); /*命令数据包复位*/
}
边栏推荐
- C language exercises (recursion)
- C实现贪吃蛇小游戏
- 2022.7.2-----leetcode.871
- 4G wireless all network solar hydrological equipment power monitoring system bms110
- MySQL的information_schema数据库
- My NVIDIA developer journey - optimizing graphics card performance
- Luogu deep foundation part 1 Introduction to language Chapter 5 array and data batch storage
- 配置交叉编译工具链和环境变量
- AWT introduction
- 注释与注解
猜你喜欢
每周小结(*63):关于正能量
报错cvc-complex-type.2.4.a: 发现了以元素 ‘base-extension‘ 开头的无效内容。应以 ‘{layoutlib}‘ 之一开头。
JS how to convert seconds into hours, minutes and seconds display
js如何将秒转换成时分秒显示
740. Delete and get points
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?
Gridview出现滚动条,组件冲突,如何解决
Leakage detection relay jy82-2p
Compound nonlinear feedback control (2)
雲原生——上雲必讀之SSH篇(常用於遠程登錄雲服務器)
随机推荐
QT qtablewidget table column top requirements ideas and codes
[March 3, 2019] MAC starts redis
win10清除快速访问-不留下痕迹
【无标题】
How does apscheduler set tasks not to be concurrent (that is, execute the next task after the first one)?
Configure cross compilation tool chain and environment variables
对List进行排序工具类,可以对字符串排序
JS how to convert seconds into hours, minutes and seconds display
Understanding of cross domain and how to solve cross domain problems
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?
How to choose the middle-aged crisis of the testing post? Stick to it or find another way out? See below
2022.7.2-----leetcode. eight hundred and seventy-one
复合非线性反馈控制(二)
How to use multithreading to export excel under massive data? Source code attached!
Grounding relay dd-1/60
JSON Web Token----JWT和传统session登录认证对比
HMS v1.0 appointment. PHP editid parameter SQL injection vulnerability (cve-2022-25491)
手动对list进行分页(参数list ,当前页,页面大小)
JS get the attribute values nested in the object
ABAP:OOALV实现增删改查功能