OpenEdv-开源电子网

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

DMA求教

[复制链接]

8

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2013-11-12
在线时间
0 小时
发表于 2014-3-14 09:22:25 | 显示全部楼层 |阅读模式
我用DMA来提取电子罗盘的信号,电子罗盘是那种模块化了的,返回值稍作处理即可读出倾角值。我用USART3连接电子罗盘,可是接收不到信号返回,
而直接用FT232是可以读到返回值的,不知是不是程序的问题?还请各位大神帮忙看看。下面上代码:
#include "stm32f10x.h"
#include "SysTickDelay.h"
#include "compass.h" 

u8 USART_RX_BUF[14];        //接收缓冲,最大14个字节.
//接收状态
u8 USART_RX_STA=0;          //接收状态标记
float heading_degree=0;
u8 sign=0;
u8 i=0;


void DMA_Config(void)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //使能USART3时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//使能USART1和GPIOB时钟

     //USART3_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);
   
    //USART3_RX  B.11
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure); 
//USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    //USART1_RX  A.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

   //USART 初始化设置
   
USART_InitStructure.USART_BaudRate = 9600;//设置波特率,一般为9600;
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(USART3, &USART_InitStructure);
USART_Init(USART1, &USART_InitStructure);
   
    USART_Cmd(USART3, ENABLE); 
USART_Cmd(USART1, ENABLE);                    //使能串口 

    /* DMA clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* USARTy RX DMA1 Channel (triggered by USARTy Rx event) Config */
DMA_DeInit(DMA1_Channel3); 
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)USART3->DR;  //DMA外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART_RX_BUF;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 8;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_Init(DMA1_Channel3, &DMA_InitStructure);

/* Enable USARTy DMA Rx and TX request */
  USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
/* Enable USARTy RX DMA1 Channel */
DMA_Cmd(DMA1_Channel3, ENABLE);
}


//校准罗盘初始角度
void cali(void)
{
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}  //发送校准命令
USART_SendData(USART3, 0x68);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x04);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x00);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x08);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x0C);
}

//保存校准
void save_cali(void)
{
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}   //发送保存校准命令
USART_SendData(USART3, 0x68);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x05);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x00);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x8A);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x00);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x8F);
}


//读取磁偏角
float Read_heading(void)
{
/* Wait until USARTy RX DMA1 Channel Transfer Complete */
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {} //发送读取磁偏角命令
USART_SendData(USART3, 0x68);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x04);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x00);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x04);
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
USART_SendData(USART3, 0x08);

while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET)
{
}
for(i=0;i<14;i++) //将电子罗盘的回应发送到串口1,利用串口调试助手接收结果
{
USART_SendData(USART1, USART_RX_BUF);
}
sign=USART_RX_BUF[11]&0x80; //判断符号的正负
heading_degree=(USART_RX_BUF[11]&0x0F)*100+(USART_RX_BUF[12]/16*10)+(USART_RX_BUF[12]%16)+(USART_RX_BUF[13]/16*10)+(USART_RX_BUF[13]%16)/100;
if (sign==0x80)
{
heading_degree=-heading_degree; //计算磁偏角
}
ms_Delay(50);
return heading_degree;
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-3-14 14:12:07 | 显示全部楼层
先不用DMA试试吧,一开始就把程序搞得这么复杂...要学会从简单到复杂。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 04:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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