OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4782|回复: 3

库版本串口3 MDA发送(改原子的库版本GSM例程)不知道为什么老是不成功

[复制链接]

2

主题

15

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2013-9-14
在线时间
1 小时
发表于 2014-11-18 15:03:29 | 显示全部楼层 |阅读模式
5金钱

代码如下,那位有弄过请帮忙看下 ,,程序那里有问题  

//串口发送缓存区  
__align(8) u8 USART3_TX_BUF[USART3_MAX_SEND_LEN];  //发送缓冲,最大USART2_MAX_SEND_LEN字节
#ifdef USART3_RX_EN           //如果使能了接收     
//串口接收缓存区  

u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];     //接收缓冲,最大USART2_MAX_RECV_LEN个字节.

 

//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
u16 USART3_RX_STA=0;    
void USART3_IRQHandler(void)
{
 u8 res3;    
 if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
 { 
 
 res3 =USART_ReceiveData(USART3);  
  if(USART3_RX_STA<USART3_MAX_RECV_LEN)  //还可以接收数据
  {
   TIM_SetCounter(TIM3,0);//计数器清空            
   if(USART3_RX_STA==0)TIM3_Set(1);   //使能定时器4的中断
   USART3_RX_BUF[USART3_RX_STA++]=res3;  //记录接收到的值 
  }else
  {
   USART3_RX_STA|=1<<15;     //强制标记接收完成
  }
 }             
}  
//初始化IO 串口2
//pclk1CLK1时钟频率(Mhz)
//bound:波特率  
void USART3_Init(u32 bound)

 NVIC_InitTypeDef NVIC_InitStructure;
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB时钟
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);

  USART_DeInit(USART3);  //复位串口2
   //USART1_TX   PB.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
  
    //USART1_RX   PB.11
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
 USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
 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(USART3, &USART_InitStructure); //初始化串口 3
 
 USART_DMACmd(USART3,USART_DMAReq_Tx,ENABLE);   //使能串口2的DMA发送
 UART_DMA_Config(DMA1_Channel2,(u32)&USART3->DR,(u32)USART3_TX_BUF);//DMA1通道2,外设为串口3,存储器为USART3_TX_BUF
 USART_Cmd(USART3, ENABLE);                    //使能串口
 
#ifdef USART3_RX_EN     //如果使能了接收
 //使能接收中断
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断  
 
 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级3
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //子优先级3
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
 TIM3_Init(999,7199);  //10ms中断
 USART3_RX_STA=0;  //清零
 TIM3_Set(0);   //关闭定时器4
#endif   

}
//串口2,printf 函数
//确保一次发送数据不超过USART2_MAX_SEND_LEN字节
void u3_printf(char* fmt,...) 

 va_list ap;
 va_start(ap,fmt);
 vsprintf((char*)USART3_TX_BUF,fmt,ap);
 va_end(ap);
 while(DMA_GetCurrDataCounter(DMA1_Channel2)!=0); //等待通道6传输完成  
 UART_DMA_Enable(DMA1_Channel2,strlen((const char*)USART3_TX_BUF));  //通过dma发送出去
}
//定时器4中断服务程序     
void TIM3_IRQHandler(void)
{  
 if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)//是更新中断
 {       
  USART3_RX_STA|=1<<15; //标记接收完成
  //LED0=!LED0;
  TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志   
  TIM3_Set(0);   //关闭TIM4 
 }    
}
//设置TIM4的开关
//sta:0,关闭;1,开启;
void TIM3_Set(u8 sta)
{
 if(sta)
 {
      
  TIM_SetCounter(TIM3,0);//计数器清空
  TIM_Cmd(TIM3, ENABLE);  //使能TIMx 
 }else TIM_Cmd(TIM3, DISABLE);//关闭定时器4   
}
//通用定时器中断初始化
//这里始终选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数  
void TIM3_Init(u16 arr,u16 psc)

 NVIC_InitTypeDef NVIC_InitStructure;
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能//TIM4时钟使能   
 
 //定时器TIM3初始化
 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 
 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断

    
 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //子优先级3
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;   //IRQ通道使能
 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
 
 
 //TIM_Cmd(TIM2, ENABLE);  //使能TIMx
}
#endif  
///////////////////////////////////////USART2 DMA发送配置部分//////////////////////////////////         
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHxMA通道CHx
//cpar:外设地址
//cmar:存储器地址   
void UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar)
{
 DMA_InitTypeDef DMA_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
  DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
 DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
 DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
 DMA_InitStructure.DMA_BufferSize = 0;  //DMA通道的DMA缓存的大小
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //数据宽度为8位
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式
 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
 DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 
}
//开启一次DMA传输
void UART_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u8 len)
{
 DMA_Cmd(DMA_CHx, DISABLE );  //关闭 指示的通道       
 DMA_SetCurrDataCounter(DMA_CHx,len);//DMA通道的DMA缓存的大小 
 DMA_Cmd(DMA_CHx, ENABLE);           //开启DMA传输
}   
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////          


 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-11-19 00:03:30 | 显示全部楼层
你先别搞DMA,看成功不成功。
一开始就把什么都加上,一步到位的代码得你到一定水平才行。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

15

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2013-9-14
在线时间
1 小时
 楼主| 发表于 2014-11-19 08:43:12 | 显示全部楼层
原子哥 你好, 把“DMA1_Channel7”改为“DMA1_Channel2”,,,,其他跟串口2配置都差不得(就是不知道那里出来)

UART_DMA_Config(DMA1_Channel2,(u32)&USART3->DR,(u32)USART3_TX_BUF);//DMA1通道2,外设为串口3,存储器为USART3_TX_BUF


while(DMA_GetCurrDataCounter(DMA1_Channel2)!=0); //等待通道6传输完成   
 UART_DMA_Enable(DMA1_Channel2,strlen((const char*)USART3_TX_BUF));  //通过dma发送出去
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-11-20 00:54:16 | 显示全部楼层
回复【3楼】maggg:
---------------------------------
你还是没明白我的意思。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 12:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表