完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
嗨,我真的很努力用我的PIC16F877 A来实现一个旋转编码器。我希望它增加一个计数器,如果它是单向旋转,并减少计数器,如果它在另一个方向旋转。到目前为止,它只增加了。请看下面的代码。我真的很感激你的建议。
以上来自于百度翻译 以下为原文 Hi, I am trying really hard to implement a rotary encoder with my PIC16F877A. I want it to increase a counter if it is spun one way, and decrease the counter if it is spun in the other direction. So far it only increase. Please see the code below. I really appreciate any suggestions. /* * File: interrupt.c * Author: Jevais * * Created on 18 June 2017, 11:08 */ // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include #include #include #include #include #define _XTAL_FRQ 20000000 #define on 1 #define off 0 #define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7 #define LED RC4 #define outputA RA0 #define B RB0 int counter; char counter_str[5]; volatile int A; void interrupt encoder (){ if (INTCON=0b00010010){ A=outputA; if (A==on) {counter=counter-1;} else if (A==off) {counter=counter+1;} } INTCON &= 0b01101001; // interrupt register cleared INTCON = 0b10010000; // global interrupt and RB0:external interrupt reset } void main(void) { LED = on; // status led on OPTION_REG = 0b00000000; // trigger set on falling edge INTCON = 0b10010000; // global interrupt and RB0:external interrupt set counter = 10; // variable initialised TRISA0 = 0xff; // port A set as input TRISB = 0xff; // port B set as input TRISC = 0x00; // port C set as output TRISD = 0x00; // port D set as output Lcd_Init(); // LCD initialised Lcd_Clear(); while(1){ sprintf(counter_str, "%.2i",counter); Lcd_Set_Cursor(1,1); Lcd_Write_String(counter_str); __delay_ms(10); } return; } |
|
相关推荐
16个回答
|
|
|
摆脱这个LIXEC.H已经包含了它,我不认为你需要任何这些:这行需要“=”,而不是“=”,但这是一个坏的测试无论如何,你正在测试的位你不感兴趣。你用这个来检测你的方向。你的编码器是这样工作的吗?大多数都需要测试两个输入来检测你要走哪条路。这是一个巨大的不。不要把ISE中的GIE位挪开。
以上来自于百度翻译 以下为原文 Get rid of this line #include xc.h has already included it for you I don't think you require any of these: #include #include #include This line needs "==", not "=" if (INTCON=0b00010010){ but it's a bad test anyway, you're testing bits you are not interested in. You're using this to detect your direction. Is that really how your encoder works? Most require testing both inputs to detect which way you're going. A=outputA; This is a huge no-no. Do NOT twiddle the GIE bit inside an ISR. INTCON &= 0b01101001; // interrupt register cleared INTCON = 0b10010000; // global interrupt and RB0:external interrupt reset |
|
|
|
|
|
我需要LCD。H,它是我做的头,这样微控制器就可以驱动LCD。我使用编码器的两个输出。第一个用于启动下降沿上的中断,第二个输出取决于旋转方向将是高或低。该输出连接到引脚RA0,这被称为OutPoA。我用这些线路重置寄存器。如果有更好的方法,请给我开导。
以上来自于百度翻译 以下为原文 I do need lcd.h, it a header I made so that the micro-controller can drive the LCD. I am using both outputs of the encoder. The first is used to initiate the interrupt on the falling edge, the second output will be high or low depending on rotation direction. That output is connected to pin RA0, which is known as outputA. I used these lines to reset the register. Please enlighten me if there is a better way of doing so. INTCON &= 0b01101001; // interrupt register cleared INTCON = 0b10010000; // global interrupt and RB0:external interrupt reset |
|
|
|
|
|
在第一行中替换为无意义的,因为第二行在结束之前写入结果。第二行集合GIE在中断之前结束,这是您必须不做的。(它是由编译器在所有中断退出代码之后放置的ReFiEE指令自动设置的。提前设置一个指令,最终会导致一个神秘的崩溃)
以上来自于百度翻译 以下为原文 Replace if (INTCON=0b00010010) with if (INTCONbits.INTF) Replace INTCON &= 0b01101001; // interrupt register cleared INTCON = 0b10010000; // global interrupt and RB0:external interrupt reset with INTCONbits.INTF = 0; You first line was pointless, as the second line over-write the result The second line set GIE before you got to the end of the interrupt, which you MUST NOT DO. (It is automatically set by the RETFIE instruction that the compiler puts after all the interrupt exit code. Setting it even one instruction earlier will eventually cause a mysterious crash) |
|
|
|
|
|
非常感谢你的帮助。不幸的是,修改没有改变任何东西。代码仍然像原来一样,只增加计数器。我的芯片有缺陷吗?当前的代码如下:.**文件:JavaIs**,创建于2017年6月18日,11:08*///COFIGG,PrimaMaul-FiCc=hs//振荡器选择位(HS振荡器)α-PrAPMA配置,WDTE=OF//看门狗定时器允许位(WDT禁用)LE位(PWRT)(Op/Prima)配置BRONE=//Brown out复位允许位(BOR使能),α-PrAPMA配置,LVP= OF//Low Voltage(单电源)在电路串行编程使能位(RB3是数字I/O,MCU上的HV必须用于编程)保护位(数据EEPROM代码保护关)α-PrAPMA配置WRT=OF//Flash程序存储器写使能位(写保护断开;所有程序存储器可由EECON控制写入)“包括”和“Lt.H.& Gt;”定义“xTalthFRQ 20000000”定义1×0定义RSRD2定义EN RD3α定义D4 RD4α定义D6RD6定义D7RD7定义定义的RC4定义计数器;Car反OSTR(5);易失性INTA;空中断编码器(if)(I)(I)γ(a==on){计数器=对1;}否则(a==off){计数器=计数器+1;}} IntercBist.Itf=0;}空主(空隙){Led=on;//状态为OpTythReg=0B90000;//在下降沿ItCon=0B10010000上触发集;//全局中断和RB0:外部InterrUPT SET计数器=10;//变量初始化TISESE2= 0xFF;//端口A设置为输入TrISB= 0xFF;//端口B设置为输入TISISC=0x00;//端口C设置为输出TrISD= 0x00;//端口D设置为输出LCDGIN();/LCD初始化LCDL CUSER();(1){SAMFETF(反OSTR,“%.2i”,计数器);LCDIStI*Curror(1,1);LCDSRead Enter字符串(反OSTR STR);γ-DelayyMS(10);}返回;}
以上来自于百度翻译 以下为原文 Thank you so much for your help thus far. Unfortunately, the modification hasn't changed anything. The code still behaves like the original, it only increases the counter. Is my chip defective? The current code is shown below. /* * File: interrupt.c * Author: Jevais * * Created on 18 June 2017, 11:08 */ // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include #include #include #define _XTAL_FRQ 20000000 #define on 1 #define off 0 #define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7 #define LED RC4 #define outputA RE2 int counter; char counter_str[5]; volatile int A; void interrupt encoder (){ if (INTCONbits.INTF){ A=outputA; if (A==on) {counter=counter-1;} else if (A==off) {counter=counter+1;} } INTCONbits.INTF = 0; } void main(void) { LED = on; // status led on OPTION_REG = 0b00000000; // trigger set on falling edge INTCON = 0b10010000; // global interrupt and RB0:external interrupt set counter = 10; // variable initialised TRISE2 = 0xff; // port A set as input TRISB = 0xff; // port B set as input TRISC = 0x00; // port C set as output TRISD = 0x00; // port D set as output Lcd_Init(); // LCD initialised Lcd_Clear(); while(1){ sprintf(counter_str, "%.2i",counter); Lcd_Set_Cursor(1,1); Lcd_Write_String(counter_str); __delay_ms(10); } return; } |
|
|
|
|
|
你不是在初始化Purt/TrISE,尽管它的值可以是所有的输入。
以上来自于百度翻译 以下为原文 You're not initializing PORTE/TRISE, though it's power-on value could be all-inputs |
|
|
|
|
|
嗨,CinziaG,我很困惑,我们不知道TrISe2= 0xFF的目的;
以上来自于百度翻译 以下为原文 Hi CinziaG, I am confused, is'nt that the purpose of TRISE2 = 0xff; |
|
|
|
|
|
哦,评论是错误的,然后我跳过了。无论如何,写完整的Trayes,所以你确信你设定了所有的PIN。同样的TrISA…
以上来自于百度翻译 以下为原文 Oh, the comment was wrong then Write to the full TRISE anyway, so you're sure you set all pins as wished. Same for TRISA... |
|
|
|
|
|
还有一件事你还没有初始化。所有的引脚都能在模拟模式下模拟输入功率。在PIC16F87A上,TAT包括大多数PARTA。PIC数据表中的PATA部分确实提到了这一点,并且告诉你写0x06来注册ADCON1以设置所有引脚到数字模式。无论引脚上的电压如何,引脚的数字读数总是会返回0。
以上来自于百度翻译 以下为原文 There is one more thing you have not initialised. All pins capable of analog input power up in analog mode. On a PIC16F877A, tat includes most of PORTA The PORTA section in the PIC datasheet does mention, this, and tell you to write 0x06 to register ADCON1 to set all pins to digital mode. If you don't, a digital read of the pin will always return 0, regardless of the voltage on the pin. |
|
|
|
|
|
是的,那是下一个点,但是PoTe不应该有PIC的模拟特性。
以上来自于百度翻译 以下为原文 Yeah, that was next point, but PORTE should not have analog features on that PIC |
|
|
|
|
|
|
|
|
|
|
|
嗯,你怎么说?我只看到了定义OutPuaRe2(然后是IRQ的PORTB,但是那个似乎是有效的……)
以上来自于百度翻译 以下为原文 Mmm, how do you say that? I see only #define outputA RE2 (then there is portB for the IRQ but that one seems to work...) |
|
|
|
|
|
有趣的是,在POST 1中,它是Roin in 5后,它是R2Re2确实有模拟输入能力的PIC。是七号。
以上来自于百度翻译 以下为原文 Interesting. In post#1 it was RA0 In post#5 it was RE2 RE2 does indeed have analog input capability on that PIC. It's AN7. |
|
|
|
|
|
啊哈…好吧,我用它已经很久了…
以上来自于百度翻译 以下为原文 ahah perfekt... good then - it's been so long since I used it... |
|
|
|
|
|
是的,从R0到R2改变输出,我认为RA0是有缺陷的。然而,使ADCON1=0x06修复了问题。我爱你Guys微笑:我非常感谢你的帮助,这在过去的一周里让我发疯了。这里是工作代码,参考:/**文件:JavaIs**,创建于2017年6月18日,11:08*///COFIGG,PrimaMaul-FiCc=hs/振荡器选择位(HS振荡器)α-PrAPMA配置,WDTE=OF//看门狗定时器允许位(WDT禁用)EL使能位(PWRT使能)Low Voltage / Prima配置BRONE=//Brown OUT重置允许位(BOR使能)α-PrAPMA配置LVP=OF//L(单电源)在电路串行编程使能位(RB3是数字I/O,MCU上的HV必须用于编程)α-PrAPMA COMPIG CPD= OF//数据EEPROM备忘录RY码保护位(数据EEPROM代码保护关)α·PrimaMac配置WRT=OF//Flash程序存储器写使能位(写保护断开;所有程序存储器可由EECON控制写入)定义了20000000×1的定义,定义了R~rd2;定义E4 rd3定义d4 rd4,定义d6rd6定义d7 rd7定义定义的RC4定义计数器;Car反OSTR(5);易失性A;空中断编码器(if){if X.H.G.(AtnNo.Itf=1){a= OutPoT;if(A==on){计数器(==off){计数器=计数器+1;}} IntercBist.Itf=0;}空主(空隙){Led=on;//状态为OpTythReg=0B90000;//在下降沿ItCONC= 0B10010000;//全局中断和RB0:外部触发设置:外部中断设置ADCON1= 0x06;//设置PATA到数字计数器=10;//变量初始化TrISA=0xFF;//端口E设置为输入TrISB= 0xFF;//端口B设置为输入TISISC=0x00;//端口C设置为输出TrISD=0x00;//端口D设置为输出LCDGIN();/LCD初始化LCDL CUSER();(1){SaveTf(反OSTR),“%.2i”,计数器;LCDSETSt*Curror(1,1);LCDSRead Enter字符串(反OSTR STR);γ-DelayyMS(10);}返回;}
以上来自于百度翻译 以下为原文 Yes did change outputA from RA0 to RE2, I thought RA0 was defective. However, making ADCON1=0x06 fix the problem. I love you guysSmile: /* * File: interrupt.c * Author: Jevais * * Created on 18 June 2017, 11:08 */ // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include #include #include #define _XTAL_FRQ 20000000 #define on 1 #define off 0 #define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7 #define LED RC4 #define outputA RA0 int counter; char counter_str[5]; volatile A; void interrupt encoder (){ if (INTCONbits.INTF==1){ A=outputA; if (A==on) {counter=counter-1;} else if (A==off) {counter=counter+1;} } INTCONbits.INTF = 0; } void main(void) { LED = on; // status led on OPTION_REG = 0b00000000; // trigger set on falling edge INTCON = 0b10010000; // global interrupt and RB0:external interrupt set ADCON1 = 0x06; // set portA to digital counter = 10; // variable initialised TRISA = 0xff; // port E set as input TRISB = 0xff; // port B set as input TRISC = 0x00; // port C set as output TRISD = 0x00; // port D set as output Lcd_Init(); // LCD initialised Lcd_Clear(); while(1){ sprintf(counter_str, "%.2i",counter); Lcd_Set_Cursor(1,1); Lcd_Write_String(counter_str); __delay_ms(10); } return; } |
|
|
|
|
|
请编辑你的帖子,并在你的代码周围放上“代码”标签。这是以前[Co.dE]和[/cO.d],但是在每个字符之间留出空格。我把它们放进去让标签可见。
以上来自于百度翻译 以下为原文 Please edit your post, and put "code" tags around your code. That is [ c o d e] before, and [ / c o d e ] after, but leave out the spaces between each character. I put them in to make the tag visible. |
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
503 浏览 0 评论
5812 浏览 9 评论
2350 浏览 8 评论
2237 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3544 浏览 3 评论
1159浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1121浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
888浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
503浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-13 21:27 , Processed in 1.240372 second(s), Total 72, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
5458