完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
大家好。我目前正在使用PIC18K22F97进行直流电机控制。我还使用一个LITLE ARDUNO tiN来实现对电机的速度和电流的数据采集,数据由UART发送。在我的PIC中,在我的主控制循环中,我所做的是(在其他的OFC之间):请求小工具等待数据,一旦数据被接收,它被存储在我的一个全局变量(In16t电流或In16t速度)中,并被用在PID调节中。我所写的用于获取数据的函数称为GETXQualAuthor(和GETZVITESSER);VITESE是法语中的速度,这是我的函数的代码(基本上都有相同的代码):USATAR1ISISRXARRADYY()){CurrANT1= EUARTAR1Read();}(EUARTAR1IISTXXRead()){EUARTAR1X写(0B000 000));}(EUARTAR1IISRXA Read y()){CurrANT2= EuSART1Ia Read();}(校验位(Currut1,7)){BITYLCR(CURANT1,7);CURANTY=(CURANT1和LT;LT;8)CurANT2;CouTou2;ITE(0B000 000 01);RANT = -Curnand;} {Curnal=(Currand 1<lt;8)} CurANT2;}返回Curnand;}这里是我的一个主要程序:{StullFig旗){int i=0;do{MeSuru-Curnal= GeTyCouthAuthor();张弛初始= PIDL Currand(Meurur-Curnter,Erurura Currand,CasigeNeURCurnor,TimealeE-Curnand,KpCurrand,KiCurnand,KdCurrand,WordNuPuth-Fravig-Currand);I++;PuthRaPrPosixCyclik(张弛初始,CouxxMyMod);}(i);10)这个循环需要以一个恒定的速度运行。我的问题是:如果我的小饰品没有及时回复,GETSQualAuthor(),将无限期地等待,因此停止我的控制,这是我不能让它发生的。我想做的是:在调用GETSqurAuthor()之前启动一个定时器;10,函数没有完成(因此,如果新的当前值没有被存储),我想跳过GET-CurrAuthor(),并让变量变成旧的值,所以MeSuriCurand将保持不变,并且控制可以继续(下一个指令,PID函数),我是一个C语言初学者。在读了我的代码之后,你可能已经注意到了。我对XC8和PIC也不太熟悉。你能告诉我怎样才能得到我想要的吗?另外,如果你有任何建议,使我的代码更快,请不要犹豫。如果我没有使自己足够清楚,我很乐意进一步解释我的问题。谢谢大家。
以上来自于百度翻译 以下为原文 Hello everyone. I am currently using PIC18K22F87 for dc motor control. I am also using a litle arduino trinket to realize the acquisition of the data regarding the speed and the current of the motor. The data is sent by UART. (I set up the uart with MCC as asynch with 9800 Bauds). On my pic, what i do in my main control loop is (between others, ofc):
Once the data is received, it is stocked in one of my global variable (int16_t current or int16_t speed) and is used in PID regulation. The functions I wrote to get data are called get_courant(); and get_vitesse(); Vitesse means speed in french Here is the code of my functions (both basically have the same code): int16_t get_courant() { uint8_t courant1; uint8_t courant2; int16_t courant; if(EUSART1_is_tx_ready()) { EUSART1_Write(0b00000001); } if(EUSART1_is_rx_ready()) { courant1= EUSART1_Read(); } if(EUSART1_is_tx_ready()) { EUSART1_Write(0b00000010); } if(EUSART1_is_rx_ready()) { courant2= EUSART1_Read(); } if (CheckBit(courant1,7)) { bit_clr(courant1,7); courant = (courant1 << 8) | courant2; courant = - courant; } else { courant = (courant1 << 8) | courant2; } return courant; } And here is a piece of my main programm : while(!Stop_flag) { int i=0; do { Mesure_courant=get_courant(); Tension_initiale = PID_Courant(Mesure_courant,Erreur_courant,Consigne_courant,Integrale_courant,Kp_courant,Ki_courant,Kd_courant,Wind_up_flag_courant); i++; Put_Rapport_Cyclique(Tension_initiale, Choix_Mode); } while(i<10); This loop needs to run at a constant speed. My problem is : at the moment, if my trinket doesn't reply in time, get_courant(); will wait indefinitely, hence stoping my control, which I cannot let happen. What I would like to do is the following :
I'm a beginner with C langage (as you may have noticed after reading my code). I'm also not very familiar with XC8 and PIC in general. Can you explain to me how to acheive what I want? Also, if you have any suggestions to make my code faster, please don't hesitate. If I didn't make myself clear enough, I would be delighted to explain my problem further. Thank you all. |
|
相关推荐
6个回答
|
|
|
我不会用看门狗来满足这种需要——最好是“紧急情况”,也就是说,“硬故障”。通常你有一个定时器和/或一个计数器沿其他操作进行:所以在每个“通行证”中,你检查你的工作(串行端口,PIDs等),* *也*一些超时…然后采取相应行动。
以上来自于百度翻译 以下为原文 I would not use Watchdog for such need - it's better left for "emergencies" i.e. hard failures. Usually you have a timer and/or a counter going on, along the other operations: so in each "pass" you check for your jobs (serial ports, PIDs etc) and *also* for some timeout... and then act accordingly. |
|
|
|
|
|
谢谢你的回答!然后我会尝试使用计时器。
以上来自于百度翻译 以下为原文 Thank you for your answer ! I will try to use a timer then. |
|
|
|
|
|
如果任何人都有其他建议或建议(即使是我提供的代码的样本),我会洗耳恭听:
以上来自于百度翻译 以下为原文 If anyone has any other tip or piece of advice to give (even regarding the samples of my code I provided), I'm all ears :) |
|
|
|
|
|
HiOk,我有一些评论给那些耳朵;1)你的通讯程序应该被转换成一个开环状态机,所以它可以为每个主循环运行一个步骤。这样,你的电机控制将与当前可用的数据连续运行,直到新的数据到达。2 -这个表达式似乎是为一个多兆赫兹的台式微处理器编写的,而不是为一个小的8位微控制器写的。对于这样一个小的MCU,你只控制一个马达,所以你只有一组数据。在这种情况下,它的功能是简单的,用全局变量代替参数,使整个程序变得更快和更小。对于程序的所有功能来说都是相同的。这个小的MCU的编码从编码到PC或类似都有一些有意义的区别。3 -请我们e代码标签(BBcode)粘贴一个程序或它的一部分在帖子中,就像我上面所做的那样。它更容易阅读。
以上来自于百度翻译 以下为原文 Hi Ok, I've got a couple of comments for those ears ;) 1 - Your communicatins setup should be converted to a open loop state machine so it can execute one step for each mainloop run. This way your motor control will run continuosly with the data currently available until new data arrives. 2 - This expression seems written for a multi gigahertz desktop microprocessor and not for a small 8 bit microcontroler. Tension_initiale = PID_Courant(Mesure_courant,Erreur_courant,Consigne_courant,Integrale_courant,Kp_courant,Ki_courant,Kd_courant,Wind_up_flag_courant); All those parameters in the "PID_Courant" function are an unnecessary burden for such a small mcu. You are controling a single motor so you only have one set of data. In this situation its simple to have the function operate with global variables instead of parameters making the whole program much faster and smaller. Same aplies for all function of the program. Coding for this small mcus has some significative differences from coding to a PC or alike. 3 - Please use code tags (bbcode) when pasting a program or part of it in a post, like I did above. Its so much easier to read. HIH |
|
|
|
|
|
看来您正在请求Curand的16位整数值,通过发送两个命令,一个用于高字节CURANT1,一个用于低字节CurANT2。如果您对“ARDUINO Trink”有控制权,您可以只发送一个命令并顺序接收两个字节。在发送命令之前,您可能不需要检查EUARTAR1IISTXXRead(),但如果您这样做,则可能需要实现超时和错误响应,类似于此:调用代码需要识别返回值为-1作为错误。您可以根据在9600波特运行时所期望的超时来调整超时,大约每秒1000个字符,或者1毫秒。所以100毫秒可能太长了。
以上来自于百度翻译 以下为原文 It seems you are requesting a 16 bit integer value for Courant, by sending two commands, one for the high byte Courant1, and one for the low byte Courant2. If you have control of the "Arduino Trinket", you could just send one command and receive two bytes sequentially. You may not actually need to check for EUSART1_is_tx_ready() before sending the command, but if you do, you might want to implement a timeout and error response, something like this: int16_t get_courant() { uint8_t courant1; uint8_t courant2; uint8_t timeout = 10; // Timeout is 10 * 10 mSec = 100 mSec int16_t courant; while(timeout>0 && !(EUSART1_is_tx_ready()) { __delay_ms(10); timeout--;} if(timeout<=0) return( -1 ); else { EUSART1_Write(0b00000001); timeout = 10; while(timeout>0 && !(EUSART1_is_rx_ready()) { __delay_ms(10); timeout--;} if(timeout<=0) return( -1 ); else { courant1= EUSART1_Read(); timeout = 10; while(timeout>0 && !(EUSART1_is_tx_ready()) { __delay_ms(10); timeout--;} if(timeout<=0) return( -1 ); else { EUSART1_Write(0b00000010); } timeout = 10; while(timeout>0 && !(EUSART1_is_rx_ready()) { __delay_ms(10); timeout--;} if(timeout<=0) return( -1 ); else courant2= EUSART1_Read(); } if (CheckBit(courant1,7)) { bit_clr(courant1,7); courant = (courant1 << 8) | courant2; courant = - courant; } else courant = (courant1 << 8) | courant2; return courant; } The calling code would need to recognize a return value of -1 as an error. You can adjust the timeouts according to what you expect when running at 9600 baud, which is about 1000 characters per second, or 1 mSec. So 100 mSec may be way too long. |
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473 浏览 0 评论
5793 浏览 9 评论
2334 浏览 8 评论
2224 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3530 浏览 3 评论
1121浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1095浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
872浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
473浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 20:25 , Processed in 1.594792 second(s), Total 87, Slave 69 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2064