完善资料让更多小伙伴认识你,还能领取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接收中断允许 } 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; } } 各种办法都试过了,包括降低波特率,提高优先级,关闭了所有其他中断,把TX发送中断改为7个空位,等等,都试过了。甚至只发送chr(04) &“197331”,结果收到的还是chr(4) &“197332”。改为不用DMA都没有问题,有没有大侠能够指点一下 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
5203 浏览 9 评论
2016 浏览 8 评论
1942 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3188 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2243 浏览 5 评论
754浏览 1评论
640浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
546浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
653浏览 0评论
552浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 23:26 , Processed in 1.004975 second(s), Total 37, Slave 30 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号