OpenEdv-开源电子网

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

用正点原子开发板做DMA控制为什么发送出来的数据不对?

[复制链接]

4

主题

6

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-11-12
在线时间
2 小时
发表于 2015-7-9 11:25:55 | 显示全部楼层 |阅读模式
5金钱
主程序:
#include "delay.h"
#include "sys.h"
//#include "usart.h"
/////////////////////预定义/////////////////////
//按键防抖值
#define  button_release_def  100
//按键延时程序实参
#define  delay_i_def         30
//USART发送/接收最大长度
#define  uart_txmaxlong_def    10
#define  uart_rxmaxlong_def    10
//USART发送地址/命令
#define  uart_txcommand1_def   0xA1   
//USART接收地址/命令
#define  uart_rxcommand1_def   0xA1   
#define  uart_rxbegin_def      0xF1   //接收结束地址
#define  uart_txbegin_def      0xF1   //发送结束地址
#define  uart_rxend_def        0xF4   //接收结束地址
#define  uart_txend_def        0xF4   //发送结束地址
//USART发送长度1
#define  uart_txlong1_def      0x05
uint8_t  uart_txlong_def=6;
//////////////////////END///////////////////////
////////////////////变量定义////////////////////
//按键防抖值
uint8_t  key1_sign=0;
uint8_t  key1_value=0;

uint8_t  key2_sign=0;
uint8_t  key2_value=0;
//UART寄存器
uint8_t  uart_tx[10];
uint8_t  uart_rx[10];
uint8_t  uart_rx_long=0;
uint8_t  uart_rx_i=0;
uint8_t  uart_rxend_sign=0;       //处理完成标志
uint8_t  Flag_Uart_Send=0;
uint8_t Uart_Send_Buffer[5]; 
uint8_t i;
//////////////////////END///////////////////////
//声明外部调用
extern void LED_Init(void);
extern void INPUT_Init(void);
extern void usart1_ini(u32 bound);
extern void DMA_Initial(DMA_Channel_TypeDef* DMA_CHx, u32 SFR_Add, u32 User_Data_Add, u16 Data_Long);
extern void DMA_Run_Enable(DMA_Channel_TypeDef*DMA_CHx, u16 Data_Long);
///////////////USART1接收协议效验////////////////
void USART1_RXD(void)
{
uint8_t  i_temp=0;
uint8_t  chksum_temp=0;

//接收完毕,处理
if(uart_rxend_sign==1)
{
//状态查询命令  COMMAND=0xA1
if(uart_rx[2]==uart_rxcommand1_def)
{
for(i_temp=0;i_temp<(uart_rx[1]-1);i_temp++)
{
chksum_temp=chksum_temp+uart_rx[i_temp];
}

//效验成功
//操作内容
for(i_temp=0;i_temp<=uart_rx[1];i_temp++)
{
uart_tx[i_temp]=uart_rx[i_temp];
}

if(Flag_Uart_Send==0)
{
Flag_Uart_Send=1;
    
DMA_Run_Enable(DMA1_Channel4,uart_txlong_def);//开始一次DMA传输!
}
}

//处理完成
for(i_temp=0;i_temp<uart_rxmaxlong_def;i_temp++)
{
uart_rx[i_temp]=0;
}

uart_rxend_sign=0;
}


}
//////////////////////END///////////////////////

////串口1DMA方式发送中断  
void DMA1_Channel4_IRQHandler(void)  
{  
    //清除标志位  
    DMA_ClearFlag(DMA1_FLAG_TC4);   
    //关闭DMA  
    DMA_Cmd(DMA1_Channel4,DISABLE);  
    //允许再次发送  
    Flag_Uart_Send = 0;  
}

//串口1中断服务程序
void USART1_IRQHandler(void)
{
  uint8_t  rxdata_temp=0;
    uint8_t  i_temp=0;

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    //接收中断
{
   //data_temp =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
//USART_SendData(USART1,data_temp);

rxdata_temp=USART_ReceiveData(USART1);
//上一次处理结束
if(uart_rxend_sign==0)
{
//判断帧头
if((rxdata_temp==uart_rxbegin_def)&&(uart_rx_i==0))
{
uart_rx[uart_rx_i]=rxdata_temp;
uart_rx_i++;
}
//接收长度
else if(uart_rx_i==1)
{
uart_rx[uart_rx_i]=rxdata_temp;
uart_rx_long=uart_rx[uart_rx_i];
uart_rx_i++;
}
//推移保存
else if((uart_rx_i>1)&&(uart_rx_i<uart_rxmaxlong_def))
{
uart_rx[uart_rx_i]=rxdata_temp;
uart_rx_i++;
}
//错误处理
else
{
uart_rx_i=0;
uart_rx_long=0;
for(i_temp=0;i_temp<uart_rxmaxlong_def;i_temp++)
{
uart_rx[i_temp]=0;
}
}

//接收结束
if(uart_rx[uart_rx_long]==uart_rxend_def)
{
uart_rx_i=0;
uart_rxend_sign=1;

//LED指示
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2)==0)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
}
}
}

int main(void)
{
delay_init();                   //延时函数初始化
NVIC_Configuration();                  //设置NVIC中断分组2:2位抢占优先级,2位响应优先级  
LED_Init();                     //初始化与LED连接的硬件接口
INPUT_Init();
usart1_ini(9600);
//uart_init(9600); //串口初始化为9600
DMA_Initial(DMA1_Channel4,(u32)(&USART1->DR),(u32)uart_tx,10);
while(1)
{
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)&&(key1_sign==0))
{
delay_ms(delay_i_def);
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==1)&&(key1_sign==0))
{
key1_sign=1;

//处理
if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2)==0)
{
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
}
else if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)&&(key1_sign==1))
{
if(key1_value>button_release_def)
{
key1_sign=0;
key1_value=0;
}
else
{
key1_value++;
}
}

if((PCin(5)==0)&&(key2_sign==0))
{
delay_ms(delay_i_def);
if((PCin(5)==0)&&(key2_sign==0))
{
key2_sign=1;

//处理
if(PAin(8)==0)
{
PAout(8)=1;
}
else
{
PAout(8)=0;
}
}
}
else if((PCin(5)==1)&&(key2_sign==1))
{
if(key2_value>button_release_def)
{
key2_sign=0;
key2_value=0;
}
else
{
key2_value++;
}
}
USART1_RXD();
}
}
MDA初始化:
#include "stm32f10x.h"
//DMA1的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHxMA通道CHx
//SFR_Add:外设地址
//User_Data_Add:存储器地址
//Data_Long:数据传输量 
void DMA_Initial(DMA_Channel_TypeDef* DMA_CHx, u32 SFR_Add, u32 User_Data_Add, u16 Data_Long)
{
DMA_InitTypeDef  DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输

    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr = SFR_Add;  //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = User_Data_Add;  //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
DMA_InitStructure.DMA_BufferSize = Data_Long;  //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发送中断设置  
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
}

//开启一次DMA传输
void DMA_Run_Enable(DMA_Channel_TypeDef*DMA_CHx, u16 Data_Long)

DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
  DMA_SetCurrDataCounter(DMA1_Channel4,Data_Long);//DMA通道的DMA缓存的大小
  DMA_Cmd(DMA_CHx, ENABLE);    //使能USART1 TX DMA1 所指示的通道 
}

USART初始化:
#include "stm32f10x.h"

//初始化IO 串口1 
//bound:波特率
void usart1_ini(u32 bound)
{
    //各结构体定义
    GPIO_InitTypeDef   GPIO_InitStructure;
USART_InitTypeDef  USART_InitStructure;
NVIC_InitTypeDef   NVIC_InitStructure;

//使能USART1,GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);

//复位串口1
  USART_DeInit(USART1);

//USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;            //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);               //初始化PA9
   
    //USART1_RX  A.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //输入上拉  //浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);               //初始化PA10

   //USART 初始化设置
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(USART1, &USART_InitStructure);               //初始化串口

   //Usart1 NVIC 配置

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);                        //根据指定的参数初始化VIC寄存器

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);          //开启接收中断
  
    USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);   //????1?DMA?? 
  
    USART_Cmd(USART1, ENABLE);                              //使能串口
}

LED工作指示灯初始化:
#include "stm32f10x.h"

//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef  GPIO_InitStructure;                    //定义一个结构体变量

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE); //使能PA,PD端口时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->A.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA.8
GPIO_SetBits(GPIOA,GPIO_Pin_8);     //PA.8 输出高

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;     //LED1-->D.2 端口配置, 推挽输出
GPIO_Init(GPIOD, &GPIO_InitStructure);   //推挽输出 ,IO口速度为50MHz
GPIO_SetBits(GPIOD,GPIO_Pin_2); //PD.2 输出高 
}

//INPUT初始化
void INPUT_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);    //使能PORTA,PORTC时钟

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);                     //关闭jtag,使能SWD,可以用SWD模式调试 为了PA15能做普通IO口

GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;              //PA15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;            //设置成上拉输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);                   //初始化GPIOA15

GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;               //PC5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;            //设置成上拉输入
  GPIO_Init(GPIOC, &GPIO_InitStructure);                   //初始化GPIOC5
 
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;               //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;            //PA0设置成输入,默认下拉  
GPIO_Init(GPIOA, &GPIO_InitStructure);                   //初始化GPIOA.0
}

发送数据:F1 05 A1 66 FD F4   接收到的数据:F1 41 33 F5 F4 


DMA.zip

4.92 MB, 下载次数: 37

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-7-9 22:59:55 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-20 07:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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