完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
用DMA0向UART1-TX发数据,出现奇怪现象,要发送的字节提前了,而且总数还是对的?
要发送的数据为 chr(04) & 197331" & chr(0x1B) & "2021Echo00202111” 接收到的是: chr(04) & 197332"& chr(0x1B) & "202EEch2**202** 经过试验发现197332最后一个2,是2021第一个2多发一遍,并且覆盖了前面的1 DMA设置: static void SendCC(uint8_t ComName) { uint8_t i ; //- ********本段为DMA为初始化部分***********/ DMACONbits.DMAEN = 0; //禁止DMA模块 DMACONbits.PRSSEL = 1; //优先级循环方案 DMAL = 0; //RAM寻址下限 DMAH = 0x8000; //RAM寻址上限 IPC3bits.U1TXIP = 7; //DMA0优先级为7 IEC0bits.DMA0IE = 0; //关闭DMA0中断 IEC0bits.DMA1IE = 0; //关闭DMA1中断 IEC1bits.DMA2IE = 0; //关闭DMA2中断 IEC1bits.DMA3IE = 0; //关闭DMA3中断 //禁用计时器中断矢量 T1CONbits.TON = 0; _T1IE = 0; IEC0bits.INT0IE = 0; //- ******************************************** //-------初始化DMA0------------------- // ******设置DMA0通道从COMM_BUF向UART1-FIFO发送数据***************** DMACH0 = 0x42; //禁止DMA0,并开始对DMA进行配置 DMASRC0 = (unsigned short int) & Send_Comm_Buf + 4 ;//设置DMA0的源数据地址 // DMASRC0 = *Send_Comm_Buf;//设置DMA0的原数据地址 DMADST0 = (unsigned short int) & U1TXREG;//设置DMA0目标地址为UART1-FIFO; DMAINT0bits.CHSEL = 0x05;//设置DMA0通道触发源为UART1 DMAINT0bits.HALFEN = 1; //设置DMA0半满中断 //------------------------------------- //写入前7个字节,即指令号+器件ID, //由于器件ID为6字节,由于某些通讯部件FIFO不支持7个字节的存入,须将器件字节分段 //现分为两段,即直接写入FIFO的,包含指令一共4个字节 Send_Comm_Buf_P = Send_Comm_Buf; U1TXREG = ComName ;//写入指令 *Send_Comm_Buf_P++ = ComName;//指令写入Buf,Buf指针加一 for (i=0;i<6;i++) { *Send_Comm_Buf_P++ = SYSID;//写入数据到Buf if (i<=2) { U1TXREG = SYSID ;//写入数据到FIFO } } // 以下针对各不同指令进行处理,不再直接写入TXBUF,而由DMA进行处理 // 发送本机基本参数, if (ComName == C_SysInf) { Send_Comm_Buf_Len = 0x1B; *Send_Comm_Buf_P++ = Send_Comm_Buf_Len;//07:指令长度 *Send_Comm_Buf_P++ = SYSMData[0];//08:出厂日期Y *Send_Comm_Buf_P++ = SYSMData[1];//09: Y *Send_Comm_Buf_P++ = SYSMData[2];//0A M *Send_Comm_Buf_P++ = SYSMData[3];//0B D *Send_Comm_Buf_P++ = SYSModel[0];//0C型号 *Send_Comm_Buf_P++ = SYSModel[1];//0D型号 *Send_Comm_Buf_P++ = SYSModel[2];//0F型号 *Send_Comm_Buf_P++ = SYSModel[3];//10型号 *Send_Comm_Buf_P++ = SYSMEdition[0];//11出厂版本号 *Send_Comm_Buf_P++ = SYSMEdition[1];//12 *Send_Comm_Buf_P++ = SYSCData[0];//13系统更新日期Y *Send_Comm_Buf_P++ = SYSCData[1];//14 Y *Send_Comm_Buf_P++ = SYSCData[2];//15 M *Send_Comm_Buf_P++ = SYSCData[3];//16 D *Send_Comm_Buf_P++ = SYSCEdition[0];//17更新的版本号 *Send_Comm_Buf_P++ = SYSCEdition[1];//18 } //启动通讯-DMA DMACNT0 = Send_Comm_Buf_Len - 7; //设置传输数据数量 U1STAHbits.UTXISEL = 0;//TX接收缓冲区有8个空位触发中断 // ********************************************************************* // **************启动DMA0*************************************** //IFS0bits.DMA0IF = 0; //清除DMA0中断标志 DMACONbits.DMAEN = 1 ; //启动DMA模块 DMACH0bits.CHEN = 1; //使能DMA0 // ************************************************************ IEC0bits.U1TXIE = 1;//开启U1中断 IEC0bits.DMA0IE = 1; //开启DMA中断 } UART设置: void UART1_Initialize(void) { // URXEN disabled; URXEN禁用; // RXBIMD RXBKIF flag when Break makes low-to-high transition after being low for at least 23/11 bit periods; // RXBIMD RXBKIF 标志当中断在低到高过渡至少23/11位期间后进行低到高转换; // UARTEN enabled;使能Uart1; // MOD Asynchronous 8-bit UART; 异步8位UART; // UTXBRK disabled; 禁止同步暂停符号发送 // BRKOVR TX line driven by shifter; TX线由移位器驱动; // UTXEN disabled; 禁止发送; // USIDL disabled; 在空闲模式下工作; // WAKE disabled; 关闭唤醒使能 // ABAUD disabled; 禁止自动波特率检测 // BRGH enabled; 高速波特率(baudclk/4) U1MODE = (0x8080 & ~(1<<15)); // disabling UARTEN bit // STSEL 1 Stop bit sent; 一个停止位 // 1 checked at RX; // BCLKMOD disabled; 使用传统技术器生成波特率具体取决于BRGH位; // SLPEN disabled; 休眠模式下关闭 // FLO Off;流控制关闭 // BCLKSEL FOSC/2; 时钟源为Fosc/2(指令周期时钟) // C0EN disabled; 校验和模式0 // RUNOVF disabled;检测到溢出错误时RX停止接受新数据 // UTXINV disabled; 输出数据不翻转,空闲状态TX高电平 // URXINV disabled; 输入数据不翻转,空闲状态为高电平 // HALFDPLX disabled; 全双工模式 U1MODEH = 0x00; // OERIE disabled; 接收缓冲区溢出中断禁止 // RXBKIF disabled; 接收暂停字符中断禁止 // RXBKIE disabled; 接收暂停字符中断标志位清除 // ABDOVF disabled; BRG尚未在自动波特率采集序列期间计满返回 // OERR disabled; 接收缓冲区溢出标志清除 // TXCIE disabled; 发送冲突中断禁止 // TXCIF disabled; 发送冲突中断标志清除 // FERIE disabled; 帧错误中断禁止 // TXMTIE disabled; 发送移位寄存器空中断禁止 // ABDOVE disabled; 自动波特率采集中断禁止 // CERIE disabled; 校验和错误中断禁止 // CERIF disabled;检验和错误中断标志清除 // PERIE disabled; 奇偶校验错误中断标志清除 U1STA = 0x00; // URXISEL RX_ONE_WORD; 在缓冲区有1个以上字节时触发接收中断 // UTXBE enabled; 发送缓冲区设为空,在UTXEN=0时写入1将复位TX FIFO指针和计数器 // UTXISEL TX_BUF_EMPTY; 发送缓冲区全空时触发中断 // URXBE enabled; 接收缓冲区为空,在URXEN=1时写入1将复位RX FIFO指针和计数器 // STPMD disabled; 在第一个或第二个停止位(取决于STSEL)的中间位置触发RXIF // TXWRE disabled; 清除写发送错误标志 U1STAH = 0x22; // BaudRate = 38400; Frequency = 4,000,000 Hz; BRG 25; U1BRG =0x19; U1BRGH = 0x00; U1P1 = 0x00; U1P2 = 0x00; U1P3 = 0x00; U1P3H = 0x00; U1TXCHK = 0x00; U1RXCHK = 0x00; U1SCCON = 0x00;// U1SCINT = 0x00; // UART1中断寄存器 // ABDIF disabled; ABAUD 未使能,或已使能但未完成自动波特率 // WUIF disabled; WAKE 未使能,或已使能但未发生唤醒事件 // ABDIE disabled; 不设置事件中断 U1INT = 0x00; IEC0bits.U1RXIE = 1;// UART1接收中断允许 } 各种办法都试过了,包括降低波特率,提高优先级,关闭了所有其他中断,把TX发送中断改为7个空位,等等,都试过了。甚至只发送chr(04) &“197331”,结果收到的还是chr(4) &“197332”。改为不用DMA都没有问题,有没有大侠能够指点一下 |
|
相关推荐
8个回答
|
|
补充一下DMA中断:
void __attribute__ ( ( interrupt, no_auto_psv ) ) _DMA0Interrupt ( void ) { static uint8_t i=0; i++; IFS0bits.DMA0IF = 0; if (DMAINT0bits.HALFEN == 1) //半满中断 { DMAINT0bits.HALFEN = 0;//下次全满中断 //U1TXREG = i; // U1TXREG = 0x48; //U1TXREG = 0x41; //U1TXREG = 0x4C; //U1TXREG = 0x46; IEC0bits.U1TXIE = 1;//开启U1中断 } else { DMAINT0bits.HALFEN = 1;//下次全满中断 //U1TXREG = 0x45; //U1TXREG = 0x6E; //U1TXREG = 0x64; } } |
|
|
|
补充一下BUF定义
//定义用于串口发送指令的buf; //该buf为直接通过TX发送的数据,包含全部格式; uint8_t Send_Comm_Buf[34];// __attribute__((space(dma))) uint8_t *Send_Comm_Buf_P;//指针 uint8_t Send_Comm_Buf_Len;//定义指令段需要发送的字节数; |
|
|
|
从来没用过dma,问题 应该出在这里,多在网上找找这方面的资料看看
|
|
9 条评论
|
|
今天好像找到问题了。
原来要发送的数据定义是这样的 //Æ÷¼þID,µ÷ÊÔ³ÌÐò¼Ù¶¨Îª197331 uint8_t SYSID[5] = { 0x31,0x39,0x37,0x33,0x33,0x31 }; //³ö³§ÈÕÆÚ£¬4×Ö½ÚYYMD£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª2021 uint8_t SYSMData[3] = {0x38,0x37,0x36,0x31}; //Ðͺţ¬4×Ö½Ú£¬ËùÓÐÐͺžù²ÉÓñàºÅ£¬µ÷ÊÔ³ÌÐò¼Ù¶¨ÎªEcho, uint8_t SYSModel[3] = {0x45,0x63,0x68,0x6f}; //³ö³§°æ±¾ºÅ£¬2×Ö½Ú£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª0£» uint8_t SYSMEdition[1] = {0x30,0x30}; //¸üÐÂÈÕÆÚ£¬4×Ö½ÚYYMD£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª2021 uint8_t SYSCData[3] = {0x32,0x30,0x32,0x31}; //¸üа汾ºÅ£¬2×Ö½Ú£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª1£» uint8_t SYSCEdition[1] ={ 0x31,0x31}; 今天突然感觉好像是错位了,就改了一下变成这样 //Æ÷¼þID,µ÷ÊÔ³ÌÐò¼Ù¶¨Îª197331 uint8_t SYSID[6] = { 0x31,0x39,0x37,0x33,0x33,0x31 }; //³ö³§ÈÕÆÚ£¬4×Ö½ÚYYMD£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª2021 uint8_t SYSMData[4] = {0x38,0x37,0x36,0x31}; //Ðͺţ¬4×Ö½Ú£¬ËùÓÐÐͺžù²ÉÓñàºÅ£¬µ÷ÊÔ³ÌÐò¼Ù¶¨ÎªEcho, uint8_t SYSModel[4] = {0x45,0x63,0x68,0x6f}; //³ö³§°æ±¾ºÅ£¬2×Ö½Ú£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª0£» uint8_t SYSMEdition[2] = {0x30,0x30}; //¸üÐÂÈÕÆÚ£¬4×Ö½ÚYYMD£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª2021 uint8_t SYSCData[4] = {0x32,0x30,0x32,0x31}; //¸üа汾ºÅ£¬2×Ö½Ú£¬µ÷ÊÔ³ÌÐò¼Ù¶¨Îª1£» uint8_t SYSCEdition[2] ={ 0x31,0x31}; 现在输出正常了 上面一行是原来定义的输出结果,下面一行是改过定义之后的 f197338876EEch201202*1??àúf ------------------------------------------------------------------ f1973318761Echo00202111??àúf ------------------------------------------------------------------ 但这是不是X-IDE有毛病吧,就算没有对齐,也不能写在别的变量里吧 |
|
|
|
今天好像找到问题了。
原来要发送的数据定义是这样的 uint8_t SYSID[5] = { 0x31,0x39,0x37,0x33,0x33,0x31 }; uint8_t SYSMData[3] = {0x38,0x37,0x36,0x31}; uint8_t SYSModel[3] = {0x45,0x63,0x68,0x6f}; uint8_t SYSMEdition[1] = {0x30,0x30}; uint8_t SYSCData[3] = {0x32,0x30,0x32,0x31}; uint8_t SYSCEdition[1] ={ 0x31,0x31}; 今天突然感觉好像是错位了,就改了一下变成这样 uint8_t SYSID[6] = { 0x31,0x39,0x37,0x33,0x33,0x31 }; uint8_t SYSMData[4] = {0x38,0x37,0x36,0x31}; uint8_t SYSModel[4] = {0x45,0x63,0x68,0x6f}; uint8_t SYSMEdition[2] = {0x30,0x30}; uint8_t SYSCData[4] = {0x32,0x30,0x32,0x31}; uint8_t SYSCEdition[2] ={ 0x31,0x31}; 现在输出正常了 上面一行是原来定义的输出结果,下面一行是所有定义的数组增加了一个改过定义之后的 f 197338 876EEch201202*1 ??àúf ------------------------------------------------------------------ f 197331 8761Echo00202111??àúf ------------------------------------------------------------------ 但这是不是X-IDE有毛病吧,就算没有对齐,也不能写在别的变量里吧 |
|
|
|
|
|
|
|
|
|
|
|
虽然还存有疑问,但问题总是解决了,就让疑问暂时留着吧!
最终输出结果: 1973312021EHALFcho00202111 End 中间的HALF是在DMA半满时插入的,END是全满时加上的。 一切OK了 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-运动追踪之编写程序
424 浏览 0 评论
855 浏览 0 评论
使用Keil建立完整的工程,并使用外部中断0触发数码管显示903
1662 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
1260 浏览 0 评论
904 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11870 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-5 07:40 , Processed in 0.929492 second(s), Total 97, Slave 81 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号