完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好!我正在尝试一个通过ADC转换来控制LED的小实验,但是我遇到了一个小问题。设备:PIC16F1824MPLAB X:V3.60编译器:XC8 V1.42目的:测量的信号是从2.8V到4.2VSeSENT1的电压:2.8V~3.3V LeD1,LeD2 OFF,LeD3 OFF,LeD4 OFF,2、3、3、4、4、4、5、4、5、3、4、6、6、5、4、5、4、4、2、7、4、2、7、4、2、7、5、2、4、2、2、4、2、4、2、4、5的问题:是正确的,那么无论我改变了电压,LED不会改变。例如,第一个信号是3.8V,ReD1~5是ON,然后我把电压改变到2.8,所有的LED都不会改变。这是我的源代码:Mc.C:Health.H:ADC.C:St.C.:我怀疑ADC只对它进行过一次采样,但是ADC功能在while循环中。
以上来自于百度翻译 以下为原文 Hi!, I'm trying a little experiment that controlling led by adc conversion, but a little problem comes to me. device: PIC16F1824 MPLAB X: v3.60 compiler: xc8 v1.42 purpose: The measured signal is the voltage which value is ranged from 2.8v to 4.2v segment1: 2.8v~3.3v LED1 on, LED2 off, LED3 off, LED4 off, LED5 off segment2: 3.3v~3.4v LED1 on, LED2 on, LED3 off, LED4 off, LED5 off segment3: 3.4v~3.6v LED1 on, LED2 on, LED3 on, LED4 off, LED5 off segment4: 3.6v~3.7v LED1 on, LED2 on, LED3 on, LED4 on, LED5 off segment5: 3.7v~4.2v LED1 on, LED2 on, LED3 on, LED4 on, LED5 on The problem is: only the first action is correct, then whatever I changed the voltage, the LED won't change. e.g. the first signal is 3.8v and LED1~5 is on, then I changed voltage to 2.8, all LED won't change. Here is my source code: main.c: #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = OFF // PLL Enable (4x PLL disabled) #pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #include "header.h" void main(void){ unsigned char low_adc_result = 0; unsigned char high_adc_result = 0; unsigned int total_adc_result = 0; System_set(); ADC_set(); //Interrupt_set(); while(1){ ADC_start(); low_adc_result = ADRESL; high_adc_result = ADRESH; VOLTAGE = ( (high_adc_result << 8) | low_adc_result); if(VOLTAGE >= 571.43 && VOLTAGE < 673.47){ // 2.8v~3.3v LED1 = 0; // LED1 on LED2 = 1; LED3 = 1; LED4 = 1; LED5 = 1; } if(VOLTAGE >= 673.47 && VOLTAGE < 693.88){ // 3.3v~3.4v LED1 = 0; LED2 = 0; LED3 = 1; LED4 = 1; LED5 = 1; } if(VOLTAGE >= 693.88 && VOLTAGE < 734.7){ // 3.4v~3.6 LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 1; LED5 = 1; } if(VOLTAGE >= 734.7 && VOLTAGE < 755.1){ // 3.6v~3.7v LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; LED5 = 1; } if(VOLTAGE >= 755.1){ // 3.7v~ LED1 = 0; LED2 = 0; LED3 = 0; LED4 = 0; LED5 = 0; } } } header.h: #define VOLTAGE total_adc_result #define LED1 LATCbits.LATC1 #define LED2 LATCbits.LATC2 #define LED3 LATCbits.LATC3 #define LED4 LATCbits.LATC4 #define LED5 LATCbits.LATC5 #define button PORTCbits.RC0 void System_set(void); void ADC_set(void); void Interrupt_set(void); void ADC_start(void); adc.c: #include #include "header.h" void ADC_set(void) { /*Port configuration*/ TRISAbits.TRISA2 = 1; // input for analog signal ANSELAbits.ANSA2 = 1; // 1 = Analog input. Pin is assigned as analog input(1). Digital input buffer disabled. /*ADC module configuration*/ ADCON1bits.ADCS = 0b111; // 111 = FRC (clock supplied from a dedicated RC oscillator) ADCON1bits.ADPREF = 0b00; // 00 = VREF+ is connected to VDD ADCON1bits.ADNREF = 0; // 0 = VREF- is connected to VSS ADCON0bits.CHS = 0b00010; // 00010 = AN2 ADCON0bits.ADON = 1; // 1 = ADC is enabled ADCON1bits.ADFM = 1; // 1 = right justified } void ADC_start(void) { //the delay instruction for wating acquisition time ADCON0bits.GO_nDONE = 1; // start converting while(PIR1bits.ADIF != 0); // waiting for completion PIR1bits.ADIF = 0; } system.c: #include #include "header.h" void System_set(void) { /*Oscillator configuration*/ OSCCONbits.SCS = 0b00; // Clock determined by FOSC<2:0> in Configuration Word 1. OSCCONbits.IRCF = 0b1101; // Internal Oscillator Frequency Select, Fosc = 4MHz /*Port configuration*/ TRISCbits.TRISC0 = 1; // button TRISCbits.TRISC1 = 0; // LED control TRISCbits.TRISC2 = 0; // LED control TRISCbits.TRISC3 = 0; // LED control TRISCbits.TRISC4 = 0; // LED control TRISCbits.TRISC5 = 0; // LED control TRISAbits.TRISA2 = 1; } I suspected that the adc only sampled it once, but adc function is inside the while loop. |
|
相关推荐
11个回答
|
|
10位ADC只给出0到1023的整数结果。因此,删除所有浮点数字(以十进制数字),因为浮点运算非常昂贵,占用大量的代码空间和循环时间。
以上来自于百度翻译 以下为原文 A 10-bit ADC gives only integer result with values from 0 to 1023. So remove all the floating point numbers (with decimal digits) as floating point math is very expensive and takes lot of code space and cycle time. Replace void ADC_start(void) { //the delay instruction for wating acquisition time ADCON0bits.GO_nDONE = 1; // start converting while(PIR1bits.ADIF != 0); // waiting for completion PIR1bits.ADIF = 0; } with void ADC_start(void) { //the delay instruction for wating acquisition time ADCON0bits.GO_nDONE = 1; // start converting while(ADCON0bits.GO_nDONE); // waiting for completion } |
|
|
|
到1: 0:我可以问为什么它在按照这个规范来改变这两个条件后会起作用:这两个条件应该是相同的影响。虽然我把函数称为“中断集”,但它不起作用。
以上来自于百度翻译 以下为原文 To 1and0: May I ask you why it works after changing while(PIR1bits.ADIF != 0); // waiting for completion to this while(ADCON0bits.GO_nDONE); // waiting for completion as per the spec: These two condition are supposed to be the same affect. Although I call the function "Interrupt_set", it doesn't work. |
|
|
|
有中断服务来中断吗?清除ISR中的ADIF标志了吗?
以上来自于百度翻译 以下为原文 Do you have an interrupt function to service the interrupt? Did you clear the ADIF flag in the ISR? |
|
|
|
我没有ISR(ItCONBITS GEE=0),我没有在ISR中清除ADIF,只是在完成AD转换之后清除它。
以上来自于百度翻译 以下为原文 I didn't have ISR (INTCONbits.GIE = 0) I didn't clear ADIF in ISR, just clear it following the completion of ad conversion instead. |
|
|
|
尝试这也与ADC中断禁用:你看到这和你的区别?
以上来自于百度翻译 以下为原文 Try this too with ADC interrupt disabled: void ADC_start(void) { //the delay instruction for wating acquisition time PIR1bits.ADIF = 0; ADCON0bits.GO_nDONE = 1; // start converting while(PIR1bits.ADIF == 0); // waiting for completion } Do you see the difference between this and yours? |
|
|
|
我可能想问另一个问题。我想LED打开或关闭,只有当按钮被按下(RC0=0)。所以,我添加了IF条件,并设置RC0到输入方向。但是…事实证明,无论按钮是否被按下,IF条件总是正确的。我已经检查了硬件,没问题。谢谢您的帮助。
以上来自于百度翻译 以下为原文 I may want to ask another question. I want to LEDs turn on or off only if the button is pressed(RC0 = 0). So, I added the if condition and set RC0 to input direction. if(PORTCbits.RC0 == 0){ do the things; } BUT... it turns out that no matter the button is pressed or not, the if condition always be true. I've checked the hardware, it's no problem. Thanks for your help. |
|
|
|
我是多么愚蠢啊!它应该是:当(Prim1B.Adif)!=1)。
以上来自于百度翻译 以下为原文 How stupid am I! It should be: while(PIR1bits.ADIF != 1). |
|
|
|
您是否禁用了与RC0引脚共享的任何模拟功能?
以上来自于百度翻译 以下为原文 Have you disabled any analog function that might share with the RC0 pin? |
|
|
|
这通常发生在PIN被配置为模拟-现在我不确定您的其他设置…
以上来自于百度翻译 以下为原文 This usually happens when the pin is configured as analog - now I'm not sure about the rest of your settings... |
|
|
|
关于这个警告,尝试替换
以上来自于百度翻译 以下为原文 Regarding this warning, try replacing low_adc_result = ADRESL; high_adc_result = ADRESH; VOLTAGE = ( (high_adc_result << 8) | low_adc_result); with VOLTAGE = ((unsigned int) ADRESH << 8) | ADRESL; |
|
|
|
1和0和ChanZig:谢谢你们两位的提醒。我应该添加这个代码:禁用模拟功能。
以上来自于百度翻译 以下为原文 To 1and0 and CinziaG: Thanks for you two's reminder. I should added this code: ANSELCbits.ANSC0 = 0; to disable analog function. |
|
|
|
只有小组成员才能发言,加入小组>>
5160 浏览 9 评论
1998 浏览 8 评论
1927 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3170 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2225 浏览 5 评论
729浏览 1评论
613浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
503浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
628浏览 0评论
526浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 13:51 , Processed in 1.525569 second(s), Total 99, Slave 82 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号