完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
您好,我已经配置了DSPIC33 FJ128GP804来运行ATFCY 20275200,配置了UART与DMA,init定时器1模块,(RX有一个拉起到68K),我用蓝牙设备发送数据(BlueGiga WT12)。现在,如果我打印TungE1和Delay1的值,则分别为1和49。这意味着任务超过1ms,等待49毫秒,然后继续。现在的问题是,如果我想把更新速率从20Hz提高到25Hz或40Hz,终端会出现一个错误,显示“端口是NPT可用”。我在这里犯的错误是什么?谢谢和问候,Akhil
以上来自于百度翻译 以下为原文 Hello, I have configured the dsPIC33FJ128GP804 to run at FCY 20275200, configured the UART with DMA, init the timer 1 module, (Rx has a pull up 6.8k) and I sent data using a bluetooth device (Bluegiga WT12). while (1) { t_start = get_starttime_in_us(); Init(BufferA); SendData_DMA(); t_end = get_endtime_in_us(); temp_1 = ((t_end - t_start)*12.6)/1000.0; // in ms at 20 MIPS - 12.6 and 40MIPS - 6.5 delay_1 = ((1000.0/FREQ) - temp_1); // should be a positive number __delay_ms(delay_1); asm("CLRWDT"); } Now If I print the values of temp_1 and delay_1, it is 1.0 and 49.0 respectively. This means the task got over by 1ms and waits for 49ms and then continue the same. Now the problem is say if I want to increase the update rate from 20Hz to 25Hz or 40Hz, the terminal throws an error showing "Ports are npt available". What is the mistake that I am making here ? Thanks and Regards, Akhil |
|
相关推荐
10个回答
|
|
XC16是否支持传递给yDelaysMy()的变量?当然XC8没有,它必须是常量,所以如果你想要可变延迟,你必须编写自己的函数来调用一个循环中的yel-DayaysMs(1)。
以上来自于百度翻译 以下为原文 Does XC16 support variables passed to _delay_ms() ? Certainly XC8 does not, it must be a constant, so you have to write your own function to call _delay_ms(1) in a loop if you want variable delay. |
|
|
|
是的,如果我没记错几个月前发生了什么事,它确实会产生可怕的代码!
以上来自于百度翻译 以下为原文 Yeah, it does and produces awful code, if I remember correctly what happened to me some months ago! |
|
|
|
在调试时,PC终端或IDE会出现错误吗?我真的不明白这里的端口是什么,也不知道“init”和“sDestDaaDMA”的代码有什么困难。苏珊
以上来自于百度翻译 以下为原文 Is that error coming form the PC terminal or from the IDE while you are debugging? I don't really understand what 'ports' are being talked about here. Also it is a bit hard to know what is happening without seeing the code for 'Init' and 'SendData_DMA'. Susan |
|
|
|
@ QHB,XC16有支持苏珊LyDayaysMS(Vall)@的支持库,错误来自PC(COM端口不可用),在IT缓冲包中,数据和发送DMA块正在做,代码是WoKinf,如果我配置更新速率20Hz,则给出预期的输出,但是我应该能够发送更快的THA。n只需要1ms就可以完成。但它没有发生,当我增加速度说25Hz,在PC上得到一个错误消息
以上来自于百度翻译 以下为原文 @qhb, XC16 has the support lib for __delay_ms(val) @Susan, The error is coming from the PC (the COM ports are not available) Init Buffer pack the data void Init(unsigned int *dest){ len_str = sizeof(str); strcpy(str,a); sprintf(temp,"%+06d",T_x1); strcat(str,temp); sprintf(temp,"%+06d",T_y1); strcat(str,temp); sprintf(temp,"%+06d",T_z1); strcat(str,temp); for (i = 0; i < len_str-1; i++) { dest = ((unsigned int)(unsigned char)str); } and Send DMA block is doing, void SendData_DMA(){ // Check for the last transmission has completed while (!U1STAbits.TRMT); DMA0CONbits.CHEN = 1;// Enable DMA0 Channel DMA0REQbits.FORCE = 1;// Manual mode: Kick-start the 1st transfer } The code is workinf and giving the expected out if I configure my update rate 20Hz, but I should be able to sent faster than that as it only takes 1ms to complete. But it is not happening and when i increase the speed to say 25Hz, gets an error message on PC |
|
|
|
老实说,我想说,你需要看看PC正在做什么,在PC上发生了什么,导致错误信息。把你的初始代码块不是实际的字符串传输的定时-“SDEDATAZARDMA”函数将在它刚开始的DMA传输时返回。根据波特率和实际发送的字符数,在延迟过期和“while”循环重复之前,您可能不发送整个字符串。一种更好的方法是等待DMA通道完成。通常字符串将以尾随空字符结束。但是,您发送的所有字符都在“STR”(稍后的Dest'”缓冲区中。这可能包括将被发送到PC的垃圾字符。此外,我对“sDestDaaDMA”函数非常谨慎:TrMT位仅指当前移位寄存器动作。我不知道你是如何设置UART或DMA通道的,但是如果UART缓冲器中还有一个字符悬而未决,那么TrMT位就看不到了。UXTBF是测试UART是否可以接受新字符的更好的比特。苏珊
以上来自于百度翻译 以下为原文 To be honest, I'd say you need to look at what the PC is doing and what occurs on the PC to cause that error message. Putting your initial code block is not timing the actual character string transfer - the 'SendData_DMA' function will return as soon as it *starts* the DMA transfer. Depending on the BAUD rate and the actual number of characters sent, you may not be sending the entire string before the delay expires and the 'while' loop repeats. A better approach would be to wait until the DMA channel completes. Typically a character string will end with the trailing NULL character. However you are sending all of the characters in the 'str' (later 'dest') buffer. This might include garbage characters that will be sent to the PC. Also I'm an cautious of that 'SendData_DMA' function: the TRMT bit only refers to the current shift register action. I don't know how you have set up the UART or the DMA channel but if there is a character still pending in the UART buffer, then the TRMT bit will not see it. UXTBF is the better bit to test if the UART can accept a new character. Susan |
|
|
|
但是PC上的什么程序产生了这个信息呢?我猜这是一些CUS程序,通过USB CDC连接接收数据。我也会猜测,在刷新率较高的情况下,CDC通道上的溢出没有正确处理,因此COM端口正在退出,产生“无COM端口”消息。只能猜测。在PC上运行的信息很少。
以上来自于百度翻译 以下为原文 But what program on the PC is producing that message? I'm guessing that it's some COMMS program, receiving data via a USB CDC connection. I'm also going to guess that at the higher refresh rate you're getting an overflow on the CDC channel that isn't handled correctly, so the COM port is dropping out, producing the "no COM ports" message. Can only guess with so little information about what's running on the PC. |
|
|
|
感谢苏珊和QHB的答复。假设我只配置UART,这个延迟“DELAY100MILISCOND()”的作用是什么?如果我使这个小于100MS,术语软件(如超终端)显示串行数据崩溃显示错误信息。如果我保持延迟100T,我就能得到我所输入的。此外,我应该能够发送14400字节/秒作为我的波特是1152K,所以最大值的TXDATA缓冲区可以是,对吗?在术语I中配置COM端口NO、波特率、数据、奇偶校验和停止位,并且它流串行数据。(由于某种原因不能附上图片)
以上来自于百度翻译 以下为原文 Thanks Susan and qhb for the reply. Suppose I only configure the UART, what is the role of this delay "Delay100milliSecond()". If I make this less than 100ms, the Term software (like Hyper terminal) to display the serial data crashes showing the error message. If I keep the delay>100ms, I get what I enter. Also I should be able to send 14400 bytes/sec as my baud is 115.2k so the max val of TxData buffer can be that, right ? On Term I configure the COM port no, baud rate, data, parity and stop bits and it streams the serial data. (not able to attach a picture by some reasons) /* * File: Main_UART.c * Author: Akhil Mohan * * Created on 4 September, 2017, 7:50 PM */ #define FCY 40000000ULL //Fcy = (Fosc/2); Fosc = 80MHz #include #include "Config.h" #include #include #include #define BAUDRATE 115200 #define BRGVAL ((FCY/BAUDRATE)/16)-1 #define OSC_Val ((FCY*8)/7372800)-2 void SetupClock(void); void SetupIOPins(void); void InitUART1(void); void Delay100milliSecond(); char *TXData = "Test Datar"; int i = 0; void __attribute__((__interrupt__,__no_auto_psv__)) _U1TXInterrupt(void){ putsUART1((unsigned int *)TXData); Delay100milliSecond(); // _RA4 = 0; // IFS0bits.U1TXIF = 0; // Clear TX Interrupt flag } int main(){ AD1PCFGL = 0xFFFF; _TRISA4 = 0; _TRISB4 = 1; SetupClock(); while(_RB4 == 1); _RA4 = 1; SetupIOPins(); InitUART1(); while(1) { asm("CLRWDT"); } } void InitUART1(){ U1MODEbits.STSEL = 0; // 1 Stop bit U1MODEbits.PDSEL = 0; // No Parity, 8 data bits U1MODEbits.ABAUD = 0; // Auto-Baud Disabled U1MODEbits.BRGH = 0; // High Speed mode U1BRG = BRGVAL; IEC0bits.U1TXIE = 1; // Enable UART TX interrupt IFS0bits.U1TXIF = 0; // clear UART1 transmitter interrupt flag U1STAbits.UTXISEL0 = 0; // Interrupt after one TX character is transmitted U1STAbits.UTXISEL1 = 0; // IEC0bits.U1RXIE = 1; // Enable UART1 receiver ISR // IFS0bits.U1RXIF = 0; //Reset RX interrupt flag U1STAbits.URXISEL = 0; // Interrupt after one RX character is received U1MODEbits.UARTEN = 1; // Enable UART U1STAbits.UTXEN = 1; // Enable UART TX1 } void SetupIOPins(){ //--------------- Pin Assignment ----------------- TRISBbits.TRISB2 = 0; //Pin 22 as output pin for UART TX PPSUnLock; PPSOutput(OUT_FN_PPS_U1TX, OUT_PIN_PPS_RP2); PPSLock; //------------------------------------------------- } void Delay100milliSecond(){ for(i=0;i<10;i++) { __delay_ms(10); } } void SetupClock(){ PLLFBD = OSC_Val; CLKDIVbits.PLLPOST = 0; // N2=2 CLKDIVbits.PLLPRE = 0; // N1=2 OSCTUN = 0; // Tune FRC oscillator,Center frequency = 7.37 MHz nominal // Disable Watch Dog Timer RCONbits.SWDTEN = 0; // Clock switch to incorporate PLL __builtin_write_OSCCONH(0x01); // Initiate Clock Switch to // FRC with PLL (NOSC=0b001) __builtin_write_OSCCONL(0x01); // Start clock switching, code eg differs bit and chk for the same // Wait for Clock switch to occur while (OSCCONbits.COSC != 0b001); // Wait for PLL to lock while(!OSCCONbits.LOCK) {}; } |
|
|
|
永远不要拖延ISR。同样,从ISR内部调用函数也不是一个好主意(因为这增加了编译器的前序码和后同步码中的指令数)。我不确定“PuthAtAR1”函数究竟如何,但它通常试图用F写入U1TxReg寄存器。Irt字符,等待UART为下一个字符做好准备,然后发送-清洗并重复,直到它看到尾随空字符。当你参与UART TX ISR时,你很可能把事情搞得一团糟。你也会遇到代码的问题,试图递归但不能。给定ITXISELN位的设置,ISR将在每个字符移动到UART的TX移位寄存器之后被调用。然而,您使用的事实是,TX ISR也被称为一旦TX侧启用,这是在结束的iNITUART!当然,ISR提升处理器优先级(以阻止发生任何相同或较低优先级的中断形式)。在调用PutSuT1函数时,它处于更高的优先级。它将尝试将第一个字符写入UXTXRG,并且(我猜)等待直到发送完成-也许通过测试UXTBF位。当发送完成后,硬件将再次尝试调用ISR,但这次它只能设置TXIF位。当普萨特!函数已经将所有字符传递给UART,但是由于UART具有4个字符缓冲器,这将是在最后5个字符(FIFO中的4个和被发送的1个)之前发送的。在115200波特中,5个字符将占用每个字符90个USEC或(例如)450USEC加上O。在PutsUT1函数中的代码的头部。如果您在PutSuth1函数完成后离开ISR,那么它将立即被调用-记住在每个字符被发送之后设置的THATXIF是否为位?因此,它将尝试立即调用PutSuT1函数。因此,取决于函数是如何编写的,它可以测试或不测试缓冲区是否能够接受另一个字符。当然,在退出ISR之前添加一个时间延迟,这可能会让UART TX缓冲区溢出。现在,您应该做的是决定是否使用A。阻塞功能(如PutSuT1)或使用中断。如果你使用中断,那么你应该把一个字符放到U1TXRG寄存器中(除非字符是尾随空),清除TXIF位,然后离开。通过混合这两种样式,你可能会把事情搞得一团糟。而且,我已经完成了实际波特的计算。基于实际Fosc的速率(i使其为79227500),并且得到大约2.34%的误差。这可能足以导致PC中的框架错误(社论:对我来说)这个故事的寓意是编写自己的代码,而不是使用库函数,这样您就知道发生了什么,尤其是使用诸如UART之类的简单外围设备。也不要尝试混合编码风格(阻塞与中断驱动),不要拖延ISRs。你已经把这件事做的比它需要的要难很多。)苏珊
以上来自于百度翻译 以下为原文 NEVER put a delay in an ISR. Also it is not a good idea to call functions from within the ISR either (as this increases the number of instructions in the preamble and post-amble code the compiler has to generate). I'm not sure exactly how the 'putsUART1' function but it normally tries to write to the U1TXREG register with the first character, waits until UART is ready for the next character and then sends that - rinse and repeat until it sees the trailing null character. By you getting involved with the UARTs Tx ISR, you are probably messing things up quite badly. You will also have problems with the code trying to be recursive but not being able to. Given the setting for the ITXISELn bits, the ISR will be called after each character is moved to the UART's Tx shift register. However you are using the fact that the Tx ISR is also called as soon as the Tx side is enabled, which is at the end of the InitUART!@ function. Of course, the ISR elevates the processor priority (to stop any same or lower priority interrupt form occurring). It is in this higher priority when you call the putsUART1 function. It will try to write the first character to the UxTXREG and (I'm guessing) wait until the send completes - perhaps by testing the UXTBF bit. When the send does complete the hardware will then try to call the ISR again, but this time it will only be able to set the TXIF bit. When the putsUART! function has passed all of the character to the UART but, because the UART has a 4 character buffer, this will be before the last 5 characters (4 in the FIFO and 1 being sent) have actually been sent. At 115200 baud, 5 characters will take about 90 uSec for each character or (say) 450uSec plus the overhead of the code in the putsUART1 function. If you were to leave the ISR as soon as the putsUART1 function completes then it would be called again immediately - remember thatTXIF bit that was set after each character was sent? Therefore it will try to call the putsUART1 function almost immediately. Therefore depending on how the function is written, it may or may not test to see if the buffer is able to take another character. Of course you add in a time delay before exiting the ISR which probably lets the UART Tx buffer flush out. Now, what you SHOULD be doing is deciding if you want to use a blocking function (such as putsUART1) OR use interrupts. If you use interrupts then you should be putting a single character into the U1TXREG register (except if the character is the trailing null), clearing the TXIF bit and then leaving. By mixing the two styles you are probably messing things up badly. Also, I've done the calculations of the actual BAUD rate based on the actual Fosc (I make it 79227500) and I get an error of approx 2.34%. That *might* be enough to cause framing errors in the PC. (Editorial: to me the moral of this story is to write your own code and not use library functions so that you know what is going on, especially with simple peripherals such as the UART. Also don't try to mix coding styles (blocking vs interrupt driven) and don't put delays in ISRs. You have made this a lot harder than it needs to be.) Susan |
|
|
|
我不知道阻塞与中断驱动的UART差异。现在从数据表学习和通过论坛输入人(谢谢你的解释)。我已经按照您的建议修改了代码,但仍然无法解决这个问题。一个好消息是我试图通过使用有线电缆连接绕过WT12蓝牙模块,发现UART正在工作。问题似乎是WT12(或者你建议缓冲区填充得更快,而且没有时间来清理和重新加载新数据)。与WT12,它工作,如果我把延迟100ms在while(1)循环。
以上来自于百度翻译 以下为原文 I was unaware of the blocking vs interrupt driven UART difference. Learning now from the datasheet and input from the people through forums (Thanks a lot for your explanation). I have modified the code as you suggested and still i could not solve the problem. One good news is I tried to bypass the WT12 bluetooth module by using a wired cable connection and found that UART is working. The problem seems to be with WT12 (either as you suggest the buffer gets filled faster and it is not getting time to clean and reload the new data). With WT12 it works only if I put a delay of 100ms in the while(1) loop. char *TXData = "Test Datar"; int i = 0; int main(){ AD1PCFGL = 0xFFFF; _TRISA4 = 0; _TRISB4 = 1; ClockSelect(); // Runs @ FCY 20275200 while(_RB4 == 1); _LATA4 = 1; SetupIOPins(); ConfigUART(); while(1) { U1MODEbits.UARTEN = 1; // Enable UART U1STAbits.UTXEN = 1; // Enable UART TX1 /* wait at least(1/115200) sec before sending first char */ //for 20MIPS - 178 and 348 for 40MIPS for(i = 0; i < 178; i++) { Nop(); } putsUART1((unsigned int *)TXData); while(BusyUART1()); asm("CLRWDT"); } } void ConfigUART(void){ U1MODEbits.STSEL = 0; // 1 Stop bit U1MODEbits.PDSEL = 0; // No Parity, 8 data bits U1MODEbits.ABAUD = 0; // Auto-Baud Disabled U1MODEbits.BRGH = 0; // High Speed mode U1BRG = BRGVAL; U1STAbits.UTXISEL0 = 0; // Interrupt after one TX character is transmitted U1STAbits.UTXISEL1 = 0; } |
|
|
|
很高兴看到您的代码为您工作。您的最新代码有几个要点:1)移动代码以使UUTART从主循环中退出。你只需要启用它一次。2)你的“延迟”循环可能是无效的-编译器可能会发现它什么也不做(取决于它如何看到“NOP”),并优化整个循环。使用调用由CimuleR3提供的“延迟”函数/宏* * If *(并且我不确定)PutSuT1函数块,直到字符被发送,那么您就不需要在BuSuthART1函数上旋转。就个人而言,如果您担心这可能发生,我会把它放在while循环的开始,在PutsUT1调用之前,以确保它可以供您使用。苏珊
以上来自于百度翻译 以下为原文 Glad to see your code is working for you. With your latest code there are a few points: 1) move the code to enable theUART out of the main loop. You only need to enable it once. 2) Your 'delay' loop may well be ineffective - the compiler might see that it is doing nothing (depending on how it sees the 'NOP') and optimise the whole loop away. Using calls to the 'delay' functions/macros provided by the compiler 3) *IF* (and I'm not sure on this) the putsUART1 function blocks until the characters are sent, then you don't need to spin on the BusyUART1 function. Personally, if you are concerned that this might happen, I'd put it at the start of the while loop, before the putsUART1 call, to make sure that it is available for your use. Susan |
|
|
|
只有小组成员才能发言,加入小组>>
5166 浏览 9 评论
2000 浏览 8 评论
1928 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3174 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2226 浏览 5 评论
734浏览 1评论
615浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
506浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
631浏览 0评论
528浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-24 23:46 , Processed in 1.370759 second(s), Total 96, Slave 80 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号