本帖最后由 hwc5201314 于 2016-5-21 20:59 编辑
碰到这个问题已经几天了,还是没解决,我这个程序主要是STM32控制sim900a发送数据到上位机,但是程序每次都是在发送了3次数据后,程序就死机了, 已经确认问题出在串口,但在网上找了很多资料还是没解决。
下面是源码:
//main.c
char tt[] = "27,30,-0.77,-1.38,-11.79,25.190205,110.248857";//测试数据
int main(void)
{
USART1_Config();//信息输出打印在电脑上--用于调试
USART2_Config();//GSM模块用到的串口
SysTick_Init();
while(sim900a_cmd("AT\r","OK",1000) != SIM900A_TRUE)
{
printf("\r\n模块响应测试不正常!!\r\n");
printf("\r\n若模块响应测试一直不正常,请检查模块的连接或是否已开启电源开关\r\n");
}
printf("\r\n通过了模块响应测试,5秒后开始GPRS测试--TCP/UDP功能\r\n");
SIM900A_DELAY(5000);
sim900a_gprs_test();
Delay_ms(100);
sim900a_gprs_send(tt);
Delay_ms(5000);
while(1)
{
sim900a_gprs_send(tt);
printf("\r\n%d\r\n",++i);
Delay_ms(10000);
}
}
//bsp_usart2.c
#include "bsp_usart2.h"
#include "bsp_SysTick.h"
#include <stdarg.h>
/// 配置USART2接收中断
static void NVIC_USART2_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the USARTy Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
* 函数名:USART2_Config
* 描述 :USART2 GPIO 配置,工作模式配置
* 输入 :无
* 输出 : 无
* 调用 :外部调用
*/
void USART2_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* config USART2 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* USART2 GPIO config */
/* Configure USART2 Tx (PA.02) as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART2 Rx (PA.03) as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART2 mode config */
USART_InitStructure.USART_BaudRate = 38400;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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_USART2_Configuration();
/* 使能串口2接收中断 */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
/*
* 函数名:fputc
* 描述 :重定向c库函数printf到USART2
* 输入 :无
* 输出 :无
* 调用 :由printf调用
*/
//int fputc(int ch, FILE *f)
//{
///* 将Printf内容发往串口 */
// USART_SendData(USART2, (unsigned char) ch);
// while (!(USART2->SR & USART_FLAG_TXE));
//
// return (ch);
//}
/*
* 函数名:itoa
* 描述 :将整形数据转换成字符串
* 输入 :-radix =10 表示10进制,其他结果为0
* -value 要转换的整形数
* -buf 转换后的字符串
* -radix = 10
* 输出 :无
* 返回 :无
* 调用 :被USART2_printf()调用
*/
static char *itoa(int value, char *string, int radix)
{
int i, d;
int flag = 0;
char *ptr = string;
/* This implementation only works for decimal numbers. */
if (radix != 10)
{
*ptr = 0;
return string;
}
if (!value)
{
*ptr++ = 0x30;
*ptr = 0;
return string;
}
/* if this is a negative value insert the minus sign. */
if (value < 0)
{
*ptr++ = '-';
/* Make the value positive. */
value *= -1;
}
for (i = 10000; i > 0; i /= 10)
{
d = value / i;
if (d || flag)
{
*ptr++ = (char)(d + 0x30);
value -= (d * i);
flag = 1;
}
}
/* Null terminate the string. */
*ptr = 0;
return string;
} /* NCL_Itoa */
#if 1
//中断缓存串口数据
#define UART_BUFF_SIZE 255
volatile uint8_t uart_p = 0;
uint8_t uart_buff[UART_BUFF_SIZE];
void bsp_USART2_IRQHandler(void)
{
if(uart_p<UART_BUFF_SIZE)
{
if(USART_GetITStatus(USART2, USART_FLAG_ORE) != RESET)
{
USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR
uart_buff[uart_p] = USART_ReceiveData(USART2);
uart_p++;
}
//溢出-如果发生溢出需要限度SR,再读DR寄存器,则可清楚不断入中断的问题
if(USART_GetFlagStatus(USART2,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART2,USART_FLAG_ORE); //读SR
uart_buff[uart_p] = USART_ReceiveData(USART2);//读DR
uart_p++;
}
}
}
//获取接收到的数据和长度
char *get_rebuff(uint8_t *len)
{
*len = uart_p;
return (char *)&uart_buff;
}
void clean_rebuff(void)
{
uart_p = 0;
}
#endif
/*
* 函数名:USART2_printf
* 描述 :格式化输出,类似于C库中的printf,但这里没有用到C库
* 输入 :-USARTx 串口通道,这里只用到了串口2,即USART2
* -Data 要发送到串口的内容的指针
* -... 其他参数
* 输出 :无
* 返回 :无
* 调用 :外部调用
* 典型应用USART2_printf( USART2, "\r\n this is a demo \r\n" );
* USART2_printf( USART2, "\r\n %d \r\n", i );
* USART2_printf( USART2, "\r\n %s \r\n", j );
*/
void USART2_printf(USART_TypeDef* USARTx, char *Data,...)
{
const char *s;
int d;
char buf[16];
va_list ap;
va_start(ap, Data);
while ( *Data != 0) // 判断是否到达字符串结束符
{
if ( *Data == 0x5c ) //'\'
{
switch ( *++Data )
{
case 'r': //回车符
USART_SendData(USARTx, 0x0d);
Data ++;
break;
case 'n': //换行符
USART_SendData(USARTx, 0x0a);
Data ++;
break;
default:
Data ++;
break;
}
}
else if ( *Data == '%')
{ //
switch ( *++Data )
{
case 's': //字符串
s = va_arg(ap, const char *);
for ( ; *s; s++)
{
USART_SendData(USARTx,*s);
while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}
Data++;
break;
case 'd': //十进制
d = va_arg(ap, int);
itoa(d, buf, 10);
for (s = buf; *s; s++)
{
USART_SendData(USARTx,*s);
while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}
Data++;
break;
default:
Data++;
break;
}
} /* end of else if */
else USART_SendData(USARTx, *Data++);
while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );
}
}
//stm32f10x_it.c
.......
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
void USART1_IRQHandler(void)
{
#if 0
bsp_USART1_IRQHandler();
#else
uint8_t ch;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
//ch = USART1->DR;
ch = USART_ReceiveData(USART1);
printf( "%c", ch ); //将接受到的数据直接返回打印
}
#endif
}
void USART2_IRQHandler(void)
{
bsp_USART2_IRQHandler();
}
...........
|
|