OpenEdv-开源电子网

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

rct6上的usart3问题

[复制链接]

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
发表于 2014-9-17 14:37:00 | 显示全部楼层 |阅读模式
5金钱
我想使用RCT6上的usart3端口,但比照zet6的usart2写的代码,DMA操作怎么都调不通,请看一下初始化代码,是否需要更改:另外需要其它代码我再贴。


void USART3_Init(u32 pclk1,u32 bound)
{      
 RCC->APB2ENR|=1<<8;    //使能PORTG口时钟 
  GPIOG->CRH&=0XFFFFFF0F; //IO状态设置
 GPIOG->CRH|=0X00000030; //IO状态设置
 RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
 GPIOA->CRL&=0XFFFF00FF; //IO状态设置
 GPIOA->CRL|=0X00008B00; //IO状态设置 
 RCC->APB1ENR|=1<<17;   //使能串口时钟  
 RCC->APB1RSTR|=1<<17;   //复位串口2
 RCC->APB1RSTR&=~(1<<17);//停止复位       
 //波特率设置
  USART3->BRR=(pclk1*1000000)/(bound);// 波特率设置 
 USART3->CR1|=0X200C;   //1位停止,无校验位.
 USART3->CR3=1<<7;    //使能串口2的DMA发送
 UART_DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)USART3_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF
#ifdef USART3_RX_EN     //如果使能了接收
 //使能接收中断
 USART3->CR1|=1<<8;     //PE中断使能
 USART3->CR1|=1<<5;     //接收缓冲区非空中断使能      
 MY_NVIC_Init(2,3,USART2_IRQn,2);//组2,最低优先级
 TIM4_Init(99,7199);  //10ms中断
 USART3_RX_STA=0;  //清零
 TIM4_Set(0);   //关闭定时器4
#endif             
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-9-17 23:30:08 | 显示全部楼层
UART_DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)USART3_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF 

USART2->DR

你确定用的是USART3???
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
 楼主| 发表于 2014-9-18 10:43:22 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
都改成usart3了,还是不行,昨天代码已修改
回复

使用道具 举报

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
 楼主| 发表于 2014-9-18 23:15:54 | 显示全部楼层

原子哥请帮忙看一下我的代码,不光是rct6上,zet的战舰上也不干活,怎么才能把usart3用起来?我写的有那里不对


这是头文件
#ifndef _USART3_H
#define _USART3_H

#include "sys.h"

//串口3驱动代码
#define USART3_MAX_RECV_LEN 800 //最大接收长度
#define USART3_MAX_SEND_LEN 800 //最大发送长度
#define USART3_RX_EN 1 //0 不接收; 1 接收

extern u8  USART3_RX_BUF[USART3_MAX_RECV_LEN];   //接收缓冲,最大USART3_MAX_RECV_LEN字节
extern u8  USART3_TX_BUF[USART3_MAX_SEND_LEN];   //发送缓冲,最大USART3_MAX_SEND_LEN字节
extern u16 USART3_RX_STA;         //接收数据状态

void USART3_Init(u32 pclk1,u32 bound);
//extern void u2_printf(char* fmt,...);
extern void TIM4_Set(u8 sta);
extern void TIM4_Init(u16 arr,u16 psc);
//extern void UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar);
//extern void UART_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u8 len);

#endif

这是C文件:

#include "delay.h"
#include "usart3.h"
#include "stdarg.h"   
#include "stdio.h"   
#include "string.h" 

u8 USART3_TX_BUF[USART3_MAX_SEND_LEN];  //发送缓冲,最大USART3_MAX_SEND_LEN字节
static void UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar);
static void UART_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u8 len);
#ifdef USART3_RX_EN           //如果使能了接收     
//串口接收缓存区  
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN];     //接收缓冲,最大USART3_MAX_RECV_LEN个字节.

u16 USART3_RX_STA=0;    
void USART3_IRQHandler(void)
{
 u8 res; 
#ifdef OS_CRITICAL_METHOD  //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
 OSIntEnter();   
#endif
 if(USART3->SR&(1<<5))//接收到数据
 { 
  res=USART3->DR;
  if((USART3_RX_STA&0x8000)==0)//接收未完成
  {
   if(USART3_RX_STA&0x4000)//接收到了0x0d
   {
    if(res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
    else USART3_RX_STA|=0x8000; //接收完成了
   }else //还没收到0X0D
   { 
    if(res==0x0d)USART3_RX_STA|=0x4000;
    else
    {
     USART3_RX_BUF[USART3_RX_STA&0X3FFF]=res;
     USART3_RX_STA++;
   //  if(USART3_RX_STA>(USART_REC_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收  
    }  
   }
  }                  
 }
#ifdef OS_CRITICAL_METHOD  //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
 OSIntExit();             
#endif

void USART3_Init(u32 pclk1,u32 bound)
{      
 RCC->APB2ENR|=1<<8;    //使能PORTG口时钟 
  GPIOG->CRH&=0XFFFFFF0F; //IO状态设置
 GPIOG->CRH|=0X00000030; //IO状态设置
 RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 
 GPIOA->CRL&=0XFFFF00FF; //IO状态设置
 GPIOA->CRL|=0X00008B00; //IO状态设置 
 RCC->APB1ENR|=1<<17;   //使能串口时钟  
 RCC->APB1RSTR|=1<<17;   //复位串口2
 RCC->APB1RSTR&=~(1<<17);//停止复位       
 //波特率设置
  USART3->BRR=(pclk1*1000000)/(bound);// 波特率设置 
 USART3->CR1|=0X200C;   //1位停止,无校验位.
 USART3->CR3=1<<7;    //使能串口2的DMA发送
 UART_DMA_Config(DMA1_Channel6,(u32)&USART3->DR,(u32)USART3_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF
#ifdef USART3_RX_EN     //如果使能了接收
 //使能接收中断
 USART3->CR1|=1<<8;     //PE中断使能
 USART3->CR1|=1<<5;     //接收缓冲区非空中断使能      
 MY_NVIC_Init(2,3,USART3_IRQn,2);//组2,最低优先级
// TIM4_Init(99,7199);  //10ms中断
 USART3_RX_STA=0;  //清零
// TIM4_Set(0);   //关闭定时器4
#endif             
}

 //串口3的printf函数
 void u3_printf(char* fmt,...) 
 { 
  va_list ap;
  va_start(ap,fmt);
  vsprintf((char*)USART3_TX_BUF,fmt,ap);
  va_end(ap);
//  memcpy(USART3_TX_BUF,fmt,10);
/*  u8 i;
  for(i=0;i<20;i++)
  {
   USART3_TX_BUF = fmt;
  }*/
 
  while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成  
  UART_DMA_Enable(DMA1_Channel7,strlen((const char*)USART3_TX_BUF));  //通过dma发送出去
}

// //设置TIM4的开关
// //sta:0,关闭;1,开启;
// static void TIM4_Set(u8 sta)
// {
//  if(sta)
//  {
//      TIM4->CNT=0;         //计数器清空
//   TIM4->CR1|=1<<0;     //使能定时器4
//  }else TIM4->CR1&=~(1<<0);//关闭定时器4   
// }

// //通用定时器中断初始化
// //这里始终选择为APB1的2倍,而APB1为36M
// //arr:自动重装值。
// //psc:时钟预分频数  
// static void TIM4_Init(u16 arr,u16 psc)
// {
//  RCC->APB1ENR|=1<<2; //TIM4时钟使能   
//   TIM4->ARR=arr;   //设定计数器自动重装值  
//  TIM4->SC=psc;   //预分频器
//   TIM4->DIER|=1<<0;   //允许更新中断    
//   TIM4->CR1|=0x01;   //使能定时器4      
//   MY_NVIC_Init(1,3,TIM4_IRQn,2);//抢占2,子优先级3,组2 在2中优先级最低        
// }
 #endif  

static void UART_DMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar)
{
  RCC->AHBENR|=1<<0;   //开启DMA1时钟
 delay_us(5);
 DMA_CHx->CPAR=cpar;   //DMA1 外设地址
 DMA_CHx->CMAR=cmar;   //DMA1,存储器地址 
 DMA_CHx->CCR=0X00000000; //复位
 DMA_CHx->CCR|=1<<4;    //从存储器读
 DMA_CHx->CCR|=0<<5;    //普通模式
 DMA_CHx->CCR|=0<<6;    //外设地址非增量模式
 DMA_CHx->CCR|=1<<7;    //存储器增量模式
 DMA_CHx->CCR|=0<<8;    //外设数据宽度为8位
 DMA_CHx->CCR|=0<<10;   //存储器数据宽度8位
 DMA_CHx->CCR|=1<<12;   //中等优先级
 DMA_CHx->CCR|=0<<14;   //非存储器到存储器模式     
}

//开启一次DMA传输
static void UART_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u8 len)
{
 DMA_CHx->CCR&=~(1<<0);       //关闭DMA传输
 DMA_CHx->CNDTR=len;          //DMA1,传输数据量
 DMA_CHx->CCR|=1<<0;          //开启DMA传输

回复

使用道具 举报

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
 楼主| 发表于 2014-9-18 23:23:37 | 显示全部楼层
回复【4楼】luxiaojun:
---------------------------------
外部调用用的是u3_printf函数发送,调用的DMA_channel7, 不知发送是否成功,接收的话,使用了终端,但没看到USART3_IRQHandler被调用,USART3_RX_STA的值也没有改变
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-9-19 00:45:41 | 显示全部楼层
回复【5楼】luxiaojun:
---------------------------------
你先别用DMA发送,用普通的发送方式,发一下试试
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
 楼主| 发表于 2014-9-21 21:15:12 | 显示全部楼层
我重新写了printf函数,如下所示,字符逐个发送,调试时发现, u3put中的while一直执行不到,而usart3->DR一直是0,发送没有成功,没有USART3_IRQHandler的中断:

 void u3_printf(char* fmt,...)  
 {  
    u8 strlength,i,ch;
  va_list ap;
  va_start(ap,fmt);
  vsprintf((char*)USART3_TX_BUF,fmt,ap);
  va_end(ap);
strlength = strlen((const char*)USART3_TX_BUF);
for(i=0;i<strlength;i++)
{
ch = USART3_TX_BUF;
  u3put(ch);
}
 
}

static u8 u3put(u8 ch)
{
USART3->DR = ch; 
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕   
return 0;
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-9-21 22:21:14 | 显示全部楼层
回复【7楼】luxiaojun:
---------------------------------
执行不到??
那你停在哪里?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

18

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2014-9-16
在线时间
3 小时
 楼主| 发表于 2014-9-22 08:59:10 | 显示全部楼层
执行了USART3->DR = ch以后就返回了,好像没有执行下面的while语句,USART3->DR 的值一直是0
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-9-22 20:58:17 | 显示全部楼层
回复【9楼】luxiaojun:
---------------------------------
怎么会不执行到while呢???
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2014-3-20
在线时间
34 小时
发表于 2014-12-8 19:32:09 | 显示全部楼层
您好,usart3您调好了么?我也是USART3 DMA发送不了,参照USART2的改的
回复

使用道具 举报

9

主题

45

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
234
金钱
234
注册时间
2014-8-13
在线时间
69 小时
发表于 2016-8-30 11:08:47 | 显示全部楼层
楼主是怎么解决的?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-29 06:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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