中级会员
 
- 积分
- 473
- 金钱
- 473
- 注册时间
- 2020-5-11
- 在线时间
- 217 小时
|
20金钱
最近有模拟SPI 的需求,但是现在被困在了从机接收上,从机接收上主要一般思路应该是两种方法1.轮询 2.中断 两种方式我都试了。现主要问题有如下:
我的主从机之间的连接只用了三个线,因为没有片选的需要所以去除了CS (其实也是因为引脚不够用),现在只有MOSI MISO CLK,连接方式如下
主 从 CLK -------------> CLK MOSI -------------> MOSI MISO -------------> MISO
- 对于轮询方式,最大的困难是在线有限的情况下,当主机准备发送,从机不知道什么时候接收,这里不用考虑从机返回,所以采用半双工。
我的做法是初始状态让CLK和MOSI都为低电平,当主机发送的时候CLK保持低电平 ,拉高MOSI,并且保持这个状态3ms。这么做的原因是我采用SPI是上升沿发送,下降沿接收,在正常情况下MOSI为高电平的时候,CLK不可能保持3ms的低电平。
主机发送如下
- void SPI_Send_Byte(u8 data)
- {
- u8 i;
- for(i = 0; i < 8; i++)
- {
- SPI_CLK(0);
- SPI_DELAY();
- if(data & 0x80)
- {
- SPI_MOSI(1);
- }
- else
- {
- SPI_MOSI(0);
- }
- data <<= 1;
- SPI_CLK(1);
- delay_us(50);
- }
- }
复制代码 从机接收如下
- u8 SPI_Receive_Byte(void)
- {
- u8 i,j,data=0;
- delay_us(50);
- for(i = 0,j=0; i < 8; i++)
- {
- delay_us(40);
- if(SPI_MOSI_PIN==1)
- {
- data |= (1<<(7-i));
- }
- delay_us(60);
- }
- return data;
- }
复制代码 现在的问题就是从机接收发送无规律性的错误,检查过CLK和MOSI的波形,都是正确的
2. 中断接收
中断的话,老是进不去
- void EXTIX_Init(void)
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- SPI_CLK_Init();
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);
- EXTI_InitStructure.EXTI_Line=EXTI_Line6;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
- EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键KEY0所在的外部中断通道
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
- NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
- }
- u8 SPI_Buffer_RX[16]={0};
- u8 SPI_Buffer_TX[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
- u8 i=0;
- u8 j=0;
- u16 rise=0;
- u16 fall=0;
- //外部中断6服务函数
- void EXTI9_5_IRQHandler(void)
- {
- delay_us(5);
- if(SPI_CLK_PIN) //上升沿,接收数据
- {
- port4=0;
- i=rise/8;
- if(SPI_MOSI_PIN) //比如说传输过来的数为1100 1010 ,高位在前
- {
- //SPI_Buffer_RX[i] |= 0x01;
- SPI_Buffer_RX[i] |= 1<<(7-(rise%8));
- }
- //SPI_Buffer_RX[i] <<= (rise%8);
- rise++;
- }
- EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE6上的中断标志位
- }
复制代码
想问问大家有没有这方面的经验。。。
|
|