战舰板SD卡读写和485通信不能同时进行

2019-08-17 07:27发布

求助各位大大,
尝试了战舰板和51单片机的485通信,成功了
然后又试了战舰板的SD卡读写,也可以
但是尝试将两个结合就出错,在SD卡读写代码上加了485通信,到了RS485_Receive_Data这里就卡住出不来了。。。求助原因

        while(1)
        {

                RS485_Receive_Data(rs_receive,lendata);  //卡在这里了

把后面的按键1 2去了就可以实现485通信。。。


主函数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"                           
#include "lcd.h"  
#include "key.h"      
#include "malloc.h"
#include "sdio_sdcard.h"   

#include "rs485.h"


//通过串口打印SD卡相关信息
void show_sdcard_info(void)
{
        switch(SDCardInfo.CardType)
        {
                case SDIO_STD_CAPACITY_SD_CARD_V1_1:printf("Card Type:SDSC V1.1 ");break;
                case SDIO_STD_CAPACITY_SD_CARD_V2_0:printf("Card Type:SDSC V2.0 ");break;
                case SDIO_HIGH_CAPACITY_SD_CARD:printf("Card Type:SDHC V2.0 ");break;
                case SDIO_MULTIMEDIA_CARD:printf("Card Type:MMC Card ");break;
        }       
          printf("Card ManufacturerID:%d ",SDCardInfo.SD_cid.ManufacturerID);        //制造商ID
        printf("Card RCA:%d ",SDCardInfo.RCA);                                                                //卡相对地址
        printf("Card Capacity:%d MB ",(u32)(SDCardInfo.CardCapacity>>20));        //显示容量
        printf("Card BlockSize:%d ",SDCardInfo.CardBlockSize);                        //显示块大小
}  

/************************************************************************************************/
int main(void)
{         
        u8 key0;
        u8 key1;         
        u32 sd_size;
        u8 t=0;       
        u8 *buf=0;
  u8 writebuf[]="A25.8 44.9 B25.4 51.5";

        u8 *lendata;                //485部分
        unsigned char rs485buf[12]="AB";  //发送地址
  unsigned char rs_receive[12];         

        delay_init();                     //延时函数初始化          
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
        uart_init(9600);                 //串口初始化为9600
        LED_Init();                                          //初始化与LED连接的硬件接口
        KEY_Init();                                        //初始化按键
        LCD_Init();                                           //初始化LCD  

        RS485_Init(9600);        //初始化RS485
         
        my_mem_init(SRAMIN);                //初始化内部内存池
        POINT_COLOR=RED;                        //设置字体为红 {MOD}
        LCD_ShowString(30,50,200,16,16,"WarShip STM32");       
        LCD_ShowString(30,70,200,16,16,"SD CARD TEST");       
        LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(30,110,200,16,16,"2015/1/20");
        LCD_ShowString(30,130,200,16,16,"KEY0:Read Sector 0");       
       
        LCD_ShowString(30,230,200,16,16,"KEY1:Send");        //显示提示信息               
        POINT_COLOR=BLUE;//设置字体为蓝 {MOD}          
        LCD_ShowString(30,250,200,16,16,"Count:");                        //显示当前计数值       
        LCD_ShowString(30,270,200,16,16,"Send Data:");                //提示发送的数据       
        LCD_ShowString(30,310,200,16,16,"Receive Data:");        //提示接收到的数据       
       
        while(SD_Init())//检测不到SD卡
        {
                LCD_ShowString(30,150,200,16,16,"SD Card Error!");
                delay_ms(500);                                       
                LCD_ShowString(30,150,200,16,16,"lease Check! ");
                delay_ms(500);
                LED0=!LED0;//DS0闪烁
        }
        show_sdcard_info();        //打印SD卡相关信息
        POINT_COLOR=BLUE;        //设置字体为蓝 {MOD}
        //检测SD卡成功                                                                                             
        LCD_ShowString(30,150,200,16,16,"SD Card OK    ");
        LCD_ShowString(30,170,200,16,16,"SD Card Size:     MB");
        LCD_ShowNum(30+13*8,170,SDCardInfo.CardCapacity>>20,5,16);//显示SD卡容量
        while(1)
        {

                RS485_Receive_Data(rs_receive,lendata);  //卡在这里了
                LCD_ShowString(30,290,50,12,16,rs485buf);
                delay_ms(10);
                LCD_ShowString(30,330,150,12,16,rs_receive);  //显示也要改
                key0=KEY_Scan(0);
                if(key0==KEY0_PRES)//KEY1按下,发送一次地址数据
                {
                        LCD_ShowString(30,290,50,12,16,rs485buf);
                        RS485_Send_Data(rs485buf+1,1);//发送1个字节   
                        delay_ms(10);                       
                }
               
//                key1=KEY_Scan(0);
                else if (key0==KEY1_PRES)//KEY1按下了
                {
                        delay_ms(10);
                        SD_WriteDisk(writebuf,0,1);
                  LCD_ShowString(30,350,200,16,16,"Write to SDcard");  
                       
                          
                }
                else if (key0==KEY2_PRES)
                {
                        buf=mymalloc(0,512);                //申请内存
                        if(buf==0)
                        {
                                LCD_ShowString(30,370,200,16,16,"Write to SDcard failed");
                                continue;
                        }
                        if(SD_ReadDisk(buf,0,1)==0)        //读取0扇区的内容
                        {       
                                LCD_ShowString(30,190,200,16,16,"USART1 Sending Data...");
                                printf("SECTOR 0 DATA: ");
                                for(sd_size=0;sd_size<512;sd_size++)printf("%x ",buf[sd_size]);//打印0扇区数据              
                                printf(" DATA ENDED ");
                                LCD_ShowString(30,190,200,16,16,"USART1 Send Data Over!");
                        }
                        myfree(0,buf);//释放内存         
                }
               


        }   
}



RS485.C文件
#include "sys.h"                    
#include "rs485.h"         
#include "delay.h"

#ifdef EN_USART2_RX           //如果使能了接收


//接收缓存区        
u8 RS485_RX_BUF[64];          //接收缓冲,最大64个字节.
//接收到的数据长度
u8 RS485_RX_CNT=0;                     

void USART2_IRQHandler(void)
{
        u8 res;            

        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收到数据
        {         
                                  
                res =USART_ReceiveData(USART2);         //读取接收到的数据
                if(RS485_RX_CNT<64)
                {
                        RS485_RX_BUF[RS485_RX_CNT]=res;                //记录接收到的值
                        RS485_RX_CNT++;                                                //接收数据增加1
                }
        }                                                                                           
}
#endif                                                                                 
//初始化IO 串口2
//pclk1CLK1时钟频率(Mhz)
//bound:波特率          
void RS485_Init(u32 bound)
{  
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);//使能GPIOA,D时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;                                 //PD7端口配置
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOD, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;        //PA2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);  

        RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
        RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位

       
#ifdef EN_USART2_RX                          //如果使能了接收
        USART_InitStructure.USART_BaudRate = bound;//波特率设置
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校验位
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式

  USART_Init(USART2, &USART_InitStructure); ; //初始化串口

        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //使能串口2中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
        NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断

  USART_Cmd(USART2, ENABLE);                    //使能串口

#endif

  RS485_TX_EN=0;                        //默认为接收模式

}

//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
        u8 t;
        RS485_TX_EN=1;                        //设置为发送模式
          for(t=0;t<len;t++)                //循环发送数据
        {                  
                while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);          
                USART_SendData(USART2,buf[t]);
        }         

        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);               
        RS485_RX_CNT=0;          
        RS485_TX_EN=0;                                //设置为接收模式       
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
        u8 rxlen=RS485_RX_CNT;
        u8 i=0;
        *len=0;                                //默认为0
        delay_ms(10);                //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
        if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
        {
                for(i=0;i<rxlen;i++)
                {
                        buf=RS485_RX_BUF;       
                }               
                *len=RS485_RX_CNT;        //记录本次数据长度
                RS485_RX_CNT=0;                //清零
        }
}



































友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
e2dward
2019-08-18 05:56
正点原子 发表于 2017-6-15 21:45
进入delay函数

单步到delay这里,再想点进去delay,直接跳到HardFault_Handler了。。。进不去

void delay_ms(u16 nms)
{                                     
        u32 temp;                  
        SysTick->LOAD=(u32)nms*fac_ms;                                //时间加载(SysTick->LOAD为24bit)
        SysTick->VAL =0x00;                                                        //清空计数器
        SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;        //开始倒数  
        do
        {
                temp=SysTick->CTRL;
        }while((temp&0x01)&&!(temp&(1<<16)));                //等待时间到达   
        SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;        //关闭计数器
        SysTick->VAL =0X00;                                               //清空计数器                      
}
#endif

一周热门 更多>