本帖最后由 lovepig200 于 2014-2-10 16:23 编辑
两个stm8l 互为主从,默认从机模式,按键后切换为主机模式发送。两个mcu可以互为主从。
main.c
#include "stm8l15x.h"
//#include "stm8_eval.h"
#include "main.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define KEYESC_PORT GPIOD // 退出出键
#define KEYESC_PIN GPIO_Pin_4
#define KEYNEX_PORT GPIOD //下一个键
#define KEYNEX_PIN GPIO_Pin_5
#define KEYESC_DOWN GPIO_ReadInputDataBit(KEYESC_PORT, KEYESC_PIN) == RESET
#define KEYNEX_DOWN GPIO_ReadInputDataBit(KEYNEX_PORT, KEYNEX_PIN) == RESET
#define LED_PORT GPIOB
#define LED_REDPIN GPIO_Pin_3
#define LED_GREPIN GPIO_Pin_4
/* Private macro -------------------------------------------------------------*/
extern uint8_t HEADER_ADDRESS_Read = (((SLAVE_ADDRESS & 0xFF00) >> 7) | 0xF1);
extern uint8_t HEADER_ADDRESS_Write;
/* Private variables ---------------------------------------------------------*/
__IO uint8_t Rx_Idx = 0, Tx_Idx = 0;
__IO uint8_t SL_Rx_Idx = 0, SL_Tx_Idx = 0;
__IO uint8_t NumByteToRead = BUFFERSIZE;
__IO uint8_t NumOfBytes = BUFFERSIZE;
unsigned char IIC_STA = 0;
uint8_t i = 0;
uint8_t p = 0;
__IO uint8_t RxBuffer[BUFFERSIZE];
TestStatus TransferStatus1 = FAILED;
extern __IO uint8_t TxBuffer[BUFFERSIZE];
/* Private function prototypes -----------------------------------------------*/
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
void Delay(__IO uint32_t nCount);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program.
* @param None
* @retval None
*/
static void GPIO_Config(void)
{
//GPIO_Init(PINA_PORT,PINA_PIN,GPIO_Mode_In_PU_No_IT);
//GPIO_Init(PINB_PORT,PINB_PIN,GPIO_Mode_In_PU_No_IT);
//GPIO_Init(OKKEY_PORT,OKKEY_PIN,GPIO_Mode_In_PU_No_IT);
GPIO_Init(LED_PORT,LED_REDPIN | LED_GREPIN,GPIO_Mode_Out_PP_Low_Slow);
//GPIO_Init(MOTER_PORT,PUL_PIN | EN_PIN | DIR_PIN,GPIO_Mode_Out_PP_Low_Slow);
//GPIO_Init(AIRP_PORT,AIRP_PIN,GPIO_Mode_In_PU_No_IT);
GPIO_Init(KEYNEX_PORT,KEYNEX_PIN,GPIO_Mode_In_PU_No_IT);
GPIO_Init(KEYESC_PORT,KEYESC_PIN,GPIO_Mode_In_PU_No_IT);
}
void I2C_SETUP(unsigned char Addr)
{
/* I2C clock Enable*/
CLK_PeripheralClockConfig(CLK_Peripheral_I2C1, ENABLE);
/* Initialize I2C peripheral */
I2C_Init(I2C1, 100000, Addr,
I2C_Mode_I2C, I2C_DutyCycle_2,
I2C_Ack_Enable, I2C_AcknowledgedAddress_7bit);
}
unsigned char I2C_MASTER_SEND(void) //应用此函数前 需要准备好要发送的数据,存在TxBuffer[]中,并设置好发送接收数据数量
{
unsigned char timeout = 0;
/* Enable Buffer and Event Interrupt*/
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_EVT | I2C_IT_BUF) , ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
while (NumOfBytes)
{
Delay(0x000F);
timeout++;
if(timeout > 10)
{
return 2;
}
}
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
return 1;
}
void I2C_MASTER_RECEIVE(__IO uint8_t *RxBuffer,unsigned char ByteToRead)
{
unsigned char Rx_Idx = 0;
/***** reception phase ***/
/* Wait while the bus is busy */
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Send START condition */
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on EV5 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
/* Send slave Address for write */
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Receiver);
/* Test on EV6 and clear it */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* While there is data to be read */
while (ByteToRead)
{
if (ByteToRead == 1)
{
/* Disable Acknowledgement */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Poll on RxNE Flag */
while ((I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET));
/* Read a byte from the Slave */
RxBuffer[Rx_Idx] = I2C_ReceiveData(I2C1);
/* Point to the next location where the byte read will be saved */
Rx_Idx++;
/* Decrement the read bytes counter */
ByteToRead--;
}
/* Test on EV7 and clear it */
if (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) )
{
/* Read a byte */
RxBuffer[Rx_Idx] = I2C_ReceiveData(I2C1);
/* Point to the next location where the byte read will be saved */
Rx_Idx++;
/* Decrement the read bytes counter */
ByteToRead--;
}
}
}
void main()
{
CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_2);
GPIO_Config();
I2C_SETUP(SLAVE_ADDRESS);
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
enableInterrupts();
while(1)
{
if(KEYESC_DOWN)
{
IIC_STA = 1;
I2C_SETUP(MASTER_ADDRESS);
GPIO_SetBits(LED_PORT, LED_REDPIN );
NumByteToRead = BUFFERSIZE;
NumOfBytes = BUFFERSIZE;
Tx_Idx = 0;
/* TXBuffer initialization */
for (i = 0; i < BUFFERSIZE; i++)
{
TxBuffer
= i;
}
p = I2C_MASTER_SEND();
/* Add a delay to be sure that communication is finished */
Delay(0x0FFF);
I2C_MASTER_RECEIVE(RxBuffer,NumByteToRead);
Delay(0xfFFF);
Delay(0xfFFF);
GPIO_ResetBits(LED_PORT, LED_REDPIN );
I2C_SETUP(SLAVE_ADDRESS);
I2C_ITConfig(I2C1, (I2C_IT_TypeDef)(I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF), ENABLE);
IIC_STA = 0;
}
}
}
/**
* @brief Inserts a delay time.
* @param nCount: specifies the delay time length.
* @retval None
*/
void Delay(__IO uint32_t nCount)
{
for (; nCount != 0; nCount--);
}
stm8l15x_it.c
#include "stm8l15x_it.h"
#include "main.h"
extern uint8_t HEADER_ADDRESS_Write = (((SLAVE_ADDRESS & 0xFF00) >> 7) | 0xF0);
extern uint8_t HEADER_ADDRESS_Read;
/* Private variables ---------------------------------------------------------*/
__IO uint8_t TxBuffer[BUFFERSIZE];
__IO uint8_t Slave_Buffer_Rx[5];
unsigned char m;
extern __IO uint8_t NumOfBytes;
extern __IO uint8_t Tx_Idx;
extern unsigned char IIC_STA ;
extern __IO uint8_t SL_Rx_Idx ;
extern __IO uint8_t SL_Tx_Idx;
INTERRUPT_HANDLER(I2C1_SPI2_IRQHandler, 29)
{
m++;
if(IIC_STA == 1)
{
switch (I2C_GetLastEvent(I2C1))
{
/* EV5 */
case I2C_EVENT_MASTER_MODE_SELECT :
/* Send slave Address for write */
I2C_Send7bitAddress(I2C1, SLAVE_ADDRESS, I2C_Direction_Transmitter);
break;
/* EV6 */
case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
if (NumOfBytes != 0)
{
/* Send the first Data */
I2C_SendData(I2C1, TxBuffer[Tx_Idx++]);
/* Decrement number of bytes */
NumOfBytes--;
}
if (NumOfBytes == 0)
{
I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
}
break;
/* EV8 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
/* Transmit Data */
I2C_SendData(I2C1, TxBuffer[Tx_Idx++]);
/* Decrement number of bytes */
NumOfBytes--;
if (NumOfBytes == 0)
{
I2C_ITConfig(I2C1, I2C_IT_BUF, DISABLE);
}
break;
/* EV8_2 */
case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
/* Send STOP condition */
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_ITConfig(I2C1, I2C_IT_EVT, DISABLE);
break;
default:
break;
}
}
else
{
/* Read SR2 register to get I2C error */
if (I2C_ReadRegister(I2C1, I2C_Register_SR2))
{
/* Clears SR2 register */
I2C1->SR2 = 0;
}
switch (I2C_GetLastEvent(I2C1))
{
/******* Slave transmitter ******/
/* check on EV1 */
case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
SL_Tx_Idx = 0;
break;
/* check on EV3 */
case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:
I2C_SendData(I2C1, 0x22);
break;
/******* Slave receiver **********/
/* check on EV1*/
case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
break;
/* Check on EV2*/
case I2C_EVENT_SLAVE_BYTE_RECEIVED:
Slave_Buffer_Rx[SL_Rx_Idx++] = I2C_ReceiveData(I2C1);
break;
/* Check on EV4 */
case (I2C_EVENT_SLAVE_STOP_DETECTED):
/* write to CR2 to clear STOPF flag */
I2C1->CR2 |= I2C_CR2_ACK;
SL_Rx_Idx=0;
break;
default:
break;
}
}
}
现象
发帖.jpg (179.57 KB, 下载次数: 2)
下载附件
通信现象
2014-2-10 16:18 上传
代码
代码.rar
(5.45 KB, 下载次数: 160)
2014-2-10 16:20 上传
点击文件名下载附件
代码
你看看这个时序图,就清楚了。在数据手册上有。
402页
iic slave.jpg (56.14 KB, 下载次数: 0)
下载附件
2014-5-5 17:42 上传
一周热门 更多>