完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
HII希望在PIC32 MX中断的一些建议。我不使用和谐或PLIBS,只是XC32 i有一个5 UART所有中断驱动系统,3是在115200和两个是9600。基本上是路由器。如果我把消息间隔开来,那么消息之间的一切都是10毫秒。但是如果加速消息到5ms或更低,那么PIC锁定或错误。PC UART使用中断SRS级别7,因为其他使用第二级改变的级别5。只有RX是中断驱动的,Testx INT是禁用的(在RX INT之间传输),所以我的问题是:1。我应该保持ISR尽可能短,还是做所有需要字节的数据包,因为上下文切换只会中断一次?2。当我进入中断时,我应该禁用所有其他中断,还是只有RX中断或根本不禁用?三。要清除RX INT标志,我应该使用掩码还是IFS0BITS?U1RXIF位如下所示?//IFS0Is.U1RxIF=0;//XC32//ItCuleFLAG(IndoSuxEl UARTAREX RX(UART1));//PLIB I/SythOrthEclipse(ItnIdIO0,InStuxCyEasARTHY1LIX);//OrthION//IFS0CLR=0x0800;//清除标志IFS0(27)RX IFS0CLR=IIFS0U1RXIFIF掩码;//XC32仅为5-64字节长H没有数据包,这是我无法控制的与其他板的通信,只有数据包到PC
以上来自于百度翻译 以下为原文 hi I would like some advice on interrupts in the PIC32MX. I am not using hARMony or PLIBS just xc32 I have a system with 5 uarts all interrupt driven, 3 are at 115200 and two are 9600. basically a router. If I send messages spaced apart then everything is fine 10ms between messages. but if a speed up messages to 5ms or lower then pic locks up or errors. The pc uart is using interrupt SRS level 7 where as the others are using level 5 with the secondary changed. only the rx are interrupt driven, the tx int are disabled (transmit inbetween rx ints). so my questions are: 1. should I keep the ISR as short as possible or do everything needed to bytes in packet as the context switch would only be once per interrupt? 2. when I enter the interrupt should I disable all other interrupts or only that rx interrupt or not disable at all? 3. to clear the rx int flag should I be using the mask or IFS0bits.U1RXIF bits see below? //IFS0bits.U1RXIF = 0; // xc32 //INTClearFlag(INT_SOURCE_UART_RX(UART1)); // plib only //PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_USART_1_RECEIVE); // harmony only //IFS0CLR = 0x08000000; // clear FLAG IFS0(27) RX IFS0CLR = _IFS0_U1RXIF_MASK; // xc32 only my packets are of 5-64 bytes long and have no end of packet, this is out of my control as communicating with other boards, only the packets to the PC are regards Ross |
|
相关推荐
17个回答
|
|
|
我建议你看一下使用DMA来完全绕过中断。已经说过,考虑一个单一的计时器中断,它足够快地收集所有的东西。我不确定你的FIFO深度或处理器速度,但是假设每一个FIFO都有8N1和4个字节,那么为了避免速度问题,你的中断以50/115200的速率进行。你可以在FIFO中有4个字节,而在一个腔室中可以有一个字节。10来自每个字节大约10位(包括开始和停止位)。没有计算器,这就像一个400美国中断。其优点是,你可以从UART中互相竞争中断中断,并保证能够及时捕获所有字节。
以上来自于百度翻译 以下为原文 I would suggest you look into using DMA to get around the interrupts entirely. That having been said, consider a single timer interrupt that is fast enough to collect everything. I'm not sure of your FIFO depth or processor speed, but assuming 8N1 and 4 bytes per FIFO, then to avoid speed issues have your interrupt do so at a rate of like 50/115200. You can have 4 bytes in the FIFO and one in the chamber so to speak. The 10 comes from roughly 10 bits per byte (start and stop bit included). Without a calculator, that's like a 400 us interrupt. The advantage is that you drop the interrupt latency from the UARTS competing against each other and are guaranteed to be able to grab all the bytes in time. |
|
|
|
|
|
感谢您的响应,我使用的是PIC32 MX795,它有一个8字节的FIFO,中断是基于字节(8N1)的。由于数据不是固定长度,或者有一个数据包的结束,所以THEMTMA将是非常困难的,因为我必须读取每个包的长度字段字节来设置DMA(不知道该怎么做),这在数据流的不同位置上,每个UART处理器的速度大约是75 MHz,我使用7.37 28 MZ OSC来获得板速率点。
以上来自于百度翻译 以下为原文 hi bblessing thanks for the response, I am using a pic32mx795 which has an 8 byte fifo, the interrupts are on a byte (8N1) basis. Because of the data is not being a fixed length or have an end of packet, then DMA would be hard as I would have to read the length field byte of each packet to set up the dma ( not sure how to do this yet) this is in different position in the data stream on each uart processor speed is about 75Mhz, I am using a 7.3728Mz osc to get the board rate spot on. regards Ross |
|
|
|
|
|
我不担心固定长度,我使用DMA的MODBUS RTU,不使用固定长度。只需使用自动启动,偶尔看一下通道指针,看看你在哪里。如果你有足够的频道,我敢打赌你可以让你的项目不受干扰。如果你不想把DMA弄得一团糟,那就行了。给定一个8字节的FIFO,你的中断频率几乎翻倍。鉴于你的系统时钟有多快,你可以每700个小时做一次定时器中断。在ISR中,只对所有UART进行投票。这里的关键是,对于不同的UART,不再有多个中断,而是一个中断。当你不接收时,它确实意味着更多的开销,因为计时器总是中断,但是你保证及时得到所有的字节。我用PIC24F和4 UART完全做到这一点,所有这些都可以高达115200。只要你的ISR只做收集和发送字节,你就可以走了。
以上来自于百度翻译 以下为原文 I wouldn't worry about fixed length, I use DMA for modbus rtu and that doesn't use fixed length. Just look at using auto-enable and occasionally looking at the channel pointer to see where you're at. If you have enough channels, I'll bet that you could make your project interrupt free. If you don't want to mess with DMA then that is ok. Given an 8 byte FIFO, your interrupt frequency nearly doubles. Given how fast your system clock is, you can make a timer interrupt once every 700 us. In that isr, just poll all of the UARTS. The key here is that you no longer have multiple interrupts for the different UARTS, but one interrupt. It does mean more overhead when you're not receiving, as the timer is always interrupting, but you're guaranteed to get all the bytes in time otherwise. I did exactly this with a PIC24F and 4 UARTS, all of which could talk up to 115200. As long as your ISR does nothing more than collect and transmit bytes, you'll be good to go. |
|
|
|
|
|
THETX INT被禁用(在RX INTS之间传输)。这是您的主要问题,您希望在115200上接收,同时在9600个“内中断”中发送相同数量的字节。为每个UART制作环形缓冲器,并且在中断中只在环形缓冲器中放置字节。这5个UART中断的优先级较高,发生了很大的混乱,使所有中断级别相同。
以上来自于百度翻译 以下为原文 the tx int are disabled (transmit inbetween rx ints). This is your major problem, how you expect to receive on 115200 and in the same time to transmit same amount of bytes in 9600 "inbetween interrupts". Make ring buffers for every UART, and in the interrupt just put bytes in the ring buffers. Also if one of these 5 UART interrupt has higher priority, a big mess can happened. Make all interrupt level same. |
|
|
|
|
|
嗨,谢谢你帮助B福尔和Cino,而对于iFook,我确实有TX打断了同样的问题。我想如果我只有RX中断,上下文切换会更少。当我有东西要发送(检查TX缓冲器全标志或空标志)时,我用字节填充TX FIFO。这个填充TX FIFO应该是处理器速度,对吧?我还认为多向量中断会处理多中断的事情吗?我确实有相同的优先级(然后默认为默认处理状态),但同样的事情发生了。我可以检查新代码,你会使用SRS的所有或软?我没有尝试过计时器的方法,好让我了解一下中断问题。我有一个定时器SPI和I2C,但这是目前禁用。我也使用了一个PWM风扇(不中断驱动)的时间。
以上来自于百度翻译 以下为原文 Hi thanks for helping bblessing and Cino and for the info ok I did have tx on interrupts which caused the same problem. I thought that if I only has rx interrupts that the context switching would be less. Plus when I have something to send (checking the tx buffer full flag or empty flag) I fill up the TX fifo with bytes. This filling up the tx fifo should be in processor speed, right? also I thought that the multivector interrupts would sort things out in terms of handling multi interrupts? I did have them the same priority (then it defaults to its default handling state), but the same thing happens. I can check with new code, would you use SRS for all or soft? I haven't tried the timer approach, good idea to get me around the interrupt issue. I do have a timer for SPI and I2C but this is disabled at present. I also use a time for a PWM fan (not interrupt driven) regards Ross |
|
|
|
|
|
出于好奇,你有多少个DMA频道?4还是8?计时器方法在您的情况下有很多意义,因为您也可以在相同的计时器中断中加载发送缓冲区。有5个UART,在正常情况下你会有10个ISR。这把你切成了一个。我会尝试为你挖掘我的旧代码,这样你就可以看到(它是基于PIC24F的,但是它应该对你有意义)。
以上来自于百度翻译 以下为原文 Out of curiosity, how many DMA channels do you have? 4 or 8? The timer approach makes a lot of sense in your case because you can also load the transmit buffers in the same timer interrupt. With 5 UARTs, you would have 10 ISRs under normal circumstances. This cuts you down to one. I'll try and exhume my old code for you so that you can see (it's based on a PIC24F, but it should make some sense to you). |
|
|
|
|
|
关于DMA的一个快速问题,我用XC32为我的所有代码,这是我的第一个PIC设计(可以使用PLIB,但Microchip已经放弃了这一和谐,所以未来的证据将是一个问题)我不喜欢和睦,不能使用它,太多隐藏。DMA容易用XC32编码,还是需要PLIB或谐波。任何示例代码(要点)都是有用的。
以上来自于百度翻译 以下为原文 hi a quick question on DMA, I am using XC32 for all my code, this is my first pic design (could use plib but microchip has ditched this for harmony, so future proof would be an issue) I don't like harmony and can't get use to it, too much hidden. is DMA easy to code with XC32 or do I require PLIB or harmony. any example code (main points) would be helpful cheers Ross |
|
|
|
|
|
我的PIC有8个DMA通道。谢谢,这将是一个很大的帮助。
以上来自于百度翻译 以下为原文 hi bblessing my pic has 8 DMA channels. thanks that would be a great help. cheers |
|
|
|
|
|
这些速度无论如何都不快。如果你有问题,你必须在中断中做一些非常慢的事情。
以上来自于百度翻译 以下为原文 These speeds are not fast by any means. If you have problems, you must be doing something outrageously slow in the interrupts. |
|
|
|
|
|
Hi NouGUI已经尝试了一个基本的ISR,它捕获一个字节,将它放在一个数组中并递增指针,从而保持ISR的快速。我还尝试了一个更复杂的ISR,它处理字节完全还原上下文切换没有成功。我真的相信我有5个赌注在哪里出问题吗?但是,我可能不是在正确处理异常吗?我在我的UART上设置了EIE错误中断使能,并检查ORR或FRE。参见代码BelvivyA.ISR(U-ARARTHAR1IVATION,IPL5SOFT)UART1HOSTING中断(空隙)/TrINAMIC1 INT/IN/CHECKING IF(IFS0BIT.U1EIF=1){IFS0BITS.U1EIF=0;CHECKRXRURUARTAR1();否则,如果(IFS0BIT.U1RXIF=1)/INTErpUT U1 {/*UARTAR2 RX*/IF(Tr11RxxErrOrthCyt==9){//循环直到缓冲空(U1Stest.UrxDa)!= 0)/在FIFO中完成的循环单元数据{APPATA.BASTTHOSTATON= ItnStEATEXRXUUART1;AppDATA U1YRXYBYEL = U1RXRG;//增量PC RX字节计数-需要知道长度字段在哪里?Rx1Tri1SytCux= RxxTri1LyCub + 1;//需要存储在正确的数组xRay-MaulsSyrxByras[RxxTri1LyCuth]=AppDATA U1X RxB字节;//存储在数组/IFS0BITS中。Orthin仅//IFS0CLR=0x0800;//清除标志IFS0(27)RX IFS0CLR=IFSF0U1RXIFIF掩码;//XC32仅(显然花费较少的时间处理)Tr11RxStReDySyByTeService=0;} //错误{APPATA.U1YRXYBYEL=U1RXRG;如果(Tr11RxxErrOrrOrthCo=0)/ /包完成{RxSiT1LyCube=0;//IFS0BITS.U1RXIF=0;/IrrOrrPICToToOx PCYTX();当发送缓冲器为空(IFS0BIT.U1TXIF=1)//FIFO空{{EC}0} /U1TXY= 0;/ /禁用发送中断//IFS0BITU.U1TXIF=0;//ItCultGrand(InthOutoSuth-UARTHARTX)(UA)//IFS0CLR=0x100000;//清除标志IFS0(28)Tx IFS0CLR=IIFS0U1TXIFIF掩码;//XC32仅}空隙{IF(U1Stest.OOR)/ /检查溢出错误{RXJTIL1MeaseGeErrErr=1;//将错误增加到PC U1SistIt.Orr==0;//清除标志清除FIFO,因此不需要xxTri1LeCub计数=0;/IFS0BIT。U1RXIF=0;//InCultFLAG(InthSoCuxEuARTHEL RX(UART1));//PLIB版本IFS0CLR=IIFS0U1RXIFIF掩码;//XC32仅//ErrOrthPICTotox PCYTX();} /(另一个错误帧)((U1SistIts.Felr=1)){RxStIL1MeaseGeErrErr=1;//向PC AppDATA读字节E= U1RxReg;Rx1 Tr1LyCube=RxxTri1SyCub + 1;//数据包Tr11-RxGyReRoRoStCyt=9RxGiT1LyCo计数;U1Stest.FER==0;//清除标志清除FIFO,因此不需要读I//IFS0BITE字节。U1RXIF=0;//InCultFLAG(InthSuthCixUARTARX RX(UART1));IFS0CLR=IFIF0SU1RXIFIFMASK,//xc32仅}这是我的基本ISR,你能看到任何问题吗?
以上来自于百度翻译 以下为原文 hi Northguy I have tried a basic isr that grabs a byte places it into an array and increments a pointer, so keeping the isr fast. I have also tried and a more complex ISR where it deals with the byte totally reducing context switch to no success. I do believe it the fact I have 5 ints going off where the problem is? but is may be I am not dealing with an exception correctly? I do set the EIE error interrupt enable on my uarts and check for OERR or FERR. see code below void __ISR(_UART_1_VECTOR, IPL5SOFT) Uart1HostInterrupt(void) // TRINAMIC1 INT { // check for error if (IFS0bits.U1EIF == 1) { IFS0bits.U1EIF = 0; checkRxErrorUART1(); } else if (IFS0bits.U1RXIF == 1) // interrupt u1 { /*USART2 RX*/ if (TRI1_RX_error_count == 9) { // loop till buffer empty while (U1STAbits.URXDA != 0) //loop unit data in fifo finished { appData.interrupt_state = INT_STATE_RX_UART1; appData.U1_rx_byte = U1RXREG; // increment pc rx byte count- need to know where length field is? rx_TRI1_count = rx_TRI1_count+1; // need to store in correct array xray_motors_RX_array[rx_TRI1_count] = appData.U1_rx_byte; // store in array //IFS0bits.U1RXIF = 0; // xc32 //INTClearFlag(INT_SOURCE_UART_RX(UART1)); // plib only //PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_USART_1_RECEIVE); // harmony only //IFS0CLR = 0x08000000; // clear FLAG IFS0(27) RX IFS0CLR = _IFS0_U1RXIF_MASK; // xc32 only (apparently take less time to process) tri1_rx_stored_byte_serviced = 0; } } else // error { appData.U1_rx_byte = U1RXREG; if (TRI1_RX_error_count = 0) // packet finished { rx_TRI1_count = 0; } //IFS0bits.U1RXIF = 0;//ERROR_PIC_TO_PC_TX(); IFS0CLR = _IFS0_U1RXIF_MASK; // xc32 only } } // interrupt generated when transmit buffer empty if (IFS0bits.U1TXIF == 1) // fifo empty { IEC0bits.U1TXIE = 0; // disable Transmit Interrupts //IFS0bits.U1TXIF = 0; //INTClearFlag(INT_SOURCE_UART_TX(UART1)); //IFS0CLR = 0x10000000; // clear FLAG IFS0(28) TX IFS0CLR = _IFS0_U1TXIF_MASK; // xc32 only } } void checkRxErrorUART1(void) { if (U1STAbits.OERR) //checking for overflow error { rx_TRI1_message_err = 1; // raise error to PC U1STAbits.OERR == 0; // clearing flag clears the fifo so no need to read byte in rx_TRI1_count = 0; //IFS0bits.U1RXIF = 0; //INTClearFlag(INT_SOURCE_UART_RX(UART1)); // plib version IFS0CLR = _IFS0_U1RXIF_MASK; // xc32 only //ERROR_PIC_TO_PC_TX(); } // another error framing if ((U1STAbits.FERR == 1)) { rx_TRI1_message_err = 1; // raise error to PC appData.U1_rx_byte = U1RXREG; rx_TRI1_count = rx_TRI1_count+1; // how many bytes left to end of packet TRI1_RX_error_count = 9-rx_TRI1_count; U1STAbits.FERR == 0; // clearing flag clears the fifo so no need to read byte in //IFS0bits.U1RXIF = 0; //INTClearFlag(INT_SOURCE_UART_RX(UART1)); IFS0CLR = _IFS0_U1RXIF_MASK; // xc32 only } } this is my basic isr, can you see any issues |
|
|
|
|
|
-在不进行任何溢出检查的情况下,将数据写入“XRayOracle SoxRx1数组”。如果它溢出,它会破坏其他地方的数据,造成一般不可预测的行为。-你的速度很慢。如果你正确地组织所有的时间,你就不会有任何错误,所以没有必要去处理它们。相反,集中精力正确处理数据。我建议使用FIFO缓冲区,也称为循环缓冲区来存储数据。你得到中断,你收到所有的字节,这是在硬件先进先出,并推动他们进入你的循环缓冲区。然后清除中断标志。这就是你所需要的。如果你不知道什么是循环缓冲器,谷歌。你需要做一个定时分析,比较数据到达和离开的速度,你需要计算出在一个单一的时间里你的PIC能坐多少数据。然后,将循环缓冲区的大小设置为满足所有需要的数据和一些额外的数据。您需要理解,如果在112500接收到,则不能在9600发送所有的数据。因此,不管你的缓冲区有多大,都会有一个时间点,你会收到一些东西,但是没有地方放它——缓冲器已经满了。显然,数据必须被驳回,但这可能还不够。在这样的情况下,你需要弄清楚你想做什么——比如使用RTS/CTS控件,停止进程,指示用户的一些错误,或者是你能想到的最好的。
以上来自于百度翻译 以下为原文 - you write data to the "xray_motors_RX_array" without making any overflow checks. If it overflows, it will corrupt data elsewhere causing generally unpredictable behaviour. - your speeds are slow. If you organize everything in time more or less correctly, you won't get any OERR, so there's no need to handle them. Instead, concentrate on handling the data correctly. I suggest you use FIFO buffers, also called circular buffers to store the data. You get to the interrupt, you receive all the bytes which are in the hardware FIFO and you push them into your circular buffer. Then you clear the interrupt flag. That's all you need. If you don't know what is a circular buffer, google it. You need to do a timing analysis comparing the speed of data arrival and departure and you need to figure out how much data can be sitting in your PIC at any single time. Then you size your circular buffer to fit all the required data and some little extra. You need to understand that if you receive at 112500, you cannot send everything out at 9600. Therefore, no matter how big your buffers are, there will be a point in time where you receive something, but there's nowhere to put it - the buffer is full. Apparently, the data must be dismissed, but this may not be enough. You need to figure out what you want to do in such situation - such as using RTS/CTS control, stopping the process, indicating some errors to the user, or whatever is the best you can think of. |
|
|
|
|
|
你好,谢谢,我只在UTXBF=0时写入缓冲区,所以停止任何ORR。我知道一个循环缓冲区是什么,它将改变我的代码。在RTS/CTS的点上,2个UART在9600没有这个,但是消息只有9个字节(固定长度)。115200的两个UART也没有流量控制,但是消息长度是5-64字节。唯一的流控制返回到PC,我设置U3MODEBIT。UENO 0=0;U3MODEBITU.UEN1=1;因此,当FIFO RX缓冲器满时,设置RTS 1。PC CTS通过收发器连接到PIC RTS,并遵循流量控制模式。我希望这足够快吗?关于罗斯
以上来自于百度翻译 以下为原文 Hi NorthGuy thanks for looking, I only write into a buffer when UTXBF == 0 so stopping any OERR. I do know what a circular buffer is and was going to change my code next for this. on the point of RTS/CTS the 2 uarts at 9600 don't have this, but the messages are only 9 bytes(fixed length). the two uarts at 115200 also don't have flow control, but there messages are 5-64 bytes long. The only flow control is back to the PC which I set U3MODEbits.UEN0 = 0; U3MODEbits.UEN1 = 1; so setting rts 1 when fifo rx buffer full. The pc cts connects to pic rts via transceiver and vise versa flow control mode. I hope this is fast enough? regards ross |
|
|
|
|
|
你必须明确(如果不使用临界部分),使用掩码位。这是atomic。否则,在清除寄存器中的位时,可能会出现RMW问题,该寄存器在不同优先级的中断中同时使用(看起来)。这也很可能是你的问题。还要注意,一些MX32处理器有持续中断,这意味着中断标志不能被清除直到中断的原因被处理(例如,RX输入寄存器被读取为UART RX中断)。/ Ruben
以上来自于百度翻译 以下为原文 You should definitely (must if not using a critical section) use the mask bits. This is atomic. Otherwise you could have RMW problems when clearing a bit in a register which is also used (seemingly) at the same time in interrupts with different priority. This might very well be your problem. Also note that some MX32 processors have persistent interrupts which means that the interrupt flag can't be cleared until the reason for the interrupt is handled (e.g. rx input register is read for an UART RX interrupt). /Ruben |
|
|
|
|
|
嗨,MaxrubenThanks,我想是读到一些地方,你应该使用CLR而不是仅仅IFS0BITU.U1RXIF=0,但是所有的例子都显示了后面的内容。所以现在我使用IFS0CLR=IFSF0U1RXIFIFASMasKi假设这是正确的吗?罗斯
以上来自于百度翻译 以下为原文 hi Maxruben Thanks, I think is read somewhere that to you should use the CLR instead of just IFS0bits.U1RXIF = 0, but all the examples show the later. so at the moment I am using IFS0CLR = _IFS0_U1RXIF_MASK I assume this is correct? Ross |
|
|
|
|
|
是的,它是正确的。否则会发生的是,清除标志的中断例程首先读取寄存器,然后清除一个位,然后再次写入寄存器。如果在中断例程正在读取寄存器之后,在写入更改的寄存器之前,另一个中断标志被设置,另一个标志也将被清除。如果第二个标志的中断有持久的中断标志,但不是所有中断都有持久的标志,这是可以的。使用一个掩码和CLR寄存器偏移来修复这一点,因为清除是在一个指令中完成的。/ Ruben
以上来自于百度翻译 以下为原文 Yes, it is correct. What otherwise can happen is that the interrupt routine that is clearing the flag first reads the register, then clears one bit and then writes back the register again. If another interrupt flag is getting set after the interrupt routine is reading the register but before writing the changed register back, the other flag will also be cleared. This can be ok if the interrupt for the second flag has persistent interrupt flags but not all interrupts has persistent flags. Using a mask and the CLR register offset fixes this since the clearing is done in one instruction. /Ruben |
|
|
|
|
|
许多PIC32中断是粘性的。这意味着,如果试图在读取缓冲区之前清除标志,标志将不清楚。
以上来自于百度翻译 以下为原文 Many PIC32 interrupts are sticky. This means that if you attempt to clear the flag before reading the buffer, the flag won't clear. |
|
|
|
|
|
我完全忘了发密码了。代码确实陈旧易碎,所以要尽量少批评。是的,对于接收器没有边界检查,但是因为头部和尾部是UTIT8YT型,缓冲器是256字节的,因此它永远不会溢出聪明的裤子(我不得不在工作中解释这无数次)。然而,在我使用它的时候,它运行得非常好。TDE的东西,BTW,在那里,因为这属于半双工RS485代码。
以上来自于百度翻译 以下为原文 I totally forgot to post code. The code is really old and crusty, so keep criticisms to a minimum. Yes, there is no bounds checking for the receiver but that is because the head and tail are of type uint8_t and the buffer is 256 bytes: therefore it can never overflow smarty-pants (I've had to explain this numerous times at work). However, it worked very well for the time that I used it. The TDE stuff, btw, is there because this pertains to half-duplex RS485 code. void __ISR(_TIMER_2_VECTOR, IPL4SOFT) Timer2Handler(void) { uint8_t dummy_val; #if MAX_NUMBER_UARTS >= 1 //RX1 while (U1STAbits.URXDA) if (U1STAbits.FERR || U1STAbits.PERR) dummy_val = U1RXREG; //dummy read else if (U1STAbits.OERR) U1STAbits.OERR = 0; //clear FIFO and receive buffer else rb[0].arr[rb[0].tail.val++] = U1RXREG; //grab a byte //TX1 if (uart_is_tx_flag[0]) while (!U1STAbits.UTXBF) { if (rb[0].head.val != rb[0].tail.val) U1TXREG = rb[0].arr[rb[0].head.val++]; else if (!U1STAbits.TRMT) break; else { if (!UART1_TDE_STATE()) uart_is_tx_flag[0] = false; UART1_TDE_OFF(); UART1_LED_OFF(); break; } } #endif #if MAX_NUMBER_UARTS >= 2 //RX2 while (U2STAbits.URXDA) if (U2STAbits.FERR || U2STAbits.PERR) dummy_val = U2RXREG; //dummy read else if (U2STAbits.OERR) U2STAbits.OERR = 0; //clear FIFO and receive buffer else rb[1].arr[rb[1].tail.val++] = U2RXREG; //grab a byte //TX2 if (uart_is_tx_flag[1]) while (!U2STAbits.UTXBF) { if (rb[1].head.val != rb[1].tail.val) U2TXREG = rb[1].arr[rb[1].head.val++]; else if (!U2STAbits.TRMT) break; else { if (!UART2_TDE_STATE()) uart_is_tx_flag[1] = false; UART2_TDE_OFF(); UART2_LED_OFF(); break; } } #endif #if MAX_NUMBER_UARTS >= 3 //RX3 while (U3STAbits.URXDA) if (U3STAbits.FERR || U3STAbits.PERR) dummy_val = U3RXREG; //dummy read else if (U3STAbits.OERR) U3STAbits.OERR = 0; //clear FIFO and receive buffer else rb[2].arr[rb[2].tail.val++] = U3RXREG; //grab a byte //TX3 if (uart_is_tx_flag[2]) while (!U3STAbits.UTXBF) { if (rb[2].head.val != rb[2].tail.val) U3TXREG = rb[2].arr[rb[2].head.val++]; else if (!U3STAbits.TRMT) break; else { if (!UART3_TDE_STATE()) uart_is_tx_flag[2] = false; UART3_TDE_OFF(); UART3_LED_OFF(); break; } } #endif #if MAX_NUMBER_UARTS >= 4 //RX4 while (U4STAbits.URXDA) if (U4STAbits.FERR || U4STAbits.PERR) dummy_val = U4RXREG; //dummy read else if (U4STAbits.OERR) U4STAbits.OERR = 0; //clear FIFO and receive buffer else rb[3].arr[rb[3].tail.val++] = U4RXREG; //grab a byte //TX4 if (uart_is_tx_flag[3]) while (!U4STAbits.UTXBF) { if (rb[3].head.val != rb[3].tail.val) U4TXREG = rb[3].arr[rb[3].head.val++]; else if (!U4STAbits.TRMT) break; else { if (!UART4_TDE_STATE()) uart_is_tx_flag[3] = false; UART4_TDE_OFF(); UART4_LED_OFF(); break; } } #endif #if MAX_NUMBER_UARTS >= 5 //RX5 while (U5STAbits.URXDA) if (U5STAbits.FERR || U5STAbits.PERR) dummy_val = U5RXREG; //dummy read else if (U5STAbits.OERR) U5STAbits.OERR = 0; //clear FIFO and receive buffer else rb[4].arr[rb[4].tail.val++] = U5RXREG; //grab a byte //TX5 if (uart_is_tx_flag[4]) while (!U5STAbits.UTXBF) { if (rb[4].head.val != rb[4].tail.val) U5TXREG = rb[4].arr[rb[4].head.val++]; else if (!U5STAbits.TRMT) break; else { if (!UART5_TDE_STATE()) uart_is_tx_flag[4] = false; UART5_TDE_OFF(); UART5_LED_OFF(); break; } } #endif // clear the interrupt flag mT2ClearIntFlag(); } |
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473 浏览 0 评论
5793 浏览 9 评论
2334 浏览 8 评论
2224 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3530 浏览 3 评论
1124浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1098浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
873浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
475浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 10:00 , Processed in 1.624748 second(s), Total 104, Slave 88 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2848