bharatwalia
Joined: 04 May 2009 Posts: 35 Location: India
|
7-segment with push buttons |
Posted: Sat May 29, 2010 2:37 am |
|
|
Hi,
This is simple program to read AC mains voltage through PIC16F876A's
ADC(channel 0) and display on 7-segment LED. I want to modify this code to include multi-tasking.
I want to increment and decrement the digits of 7-segment, but side by side ADC keeps on reading the mains voltage.
I have used three buttons: PIN_C1(increment), PIN_C2(enter mode) and
PIN_C3(decrement).
This is code is working perfect in case of reading voltage, but I am having issues when I increment or decrement the digits. The display keeps flickering between mains voltage and the digits I am changing.
Please help me.
Thanks
Bharat.
Code: |
/*Author:B.S.Walia
Company:Sunoxer.
Voltmeter 0-300V.with 0.3V precision
via 7-segment display LED.
*/
#include <16f876A.h>
#device adc=10
#USE DELAY( CLOCK=4000000 ) /* Using a 4 Mhz clock */
#FUSES XT,NOWDT,NOPROTECT,NOPUT
#include <button.c>
// This gives an RTCC interrupt rate of 100.16 Hz
// (approx. 10 ms) to sample and debounce the buttons.
#define RTCC_PRELOAD (256-5) //be carefull to prevent bouncing of control b/w main and rtcc
#define TMR1RESET2 (256-39)
// These are the "Bvar" variables required by Button.c.
int8 C1 = 0; // For the button on pin C1
int8 C2 = 0; // For the button on pin C2
int8 C3 = 0; // For the button on pin C3
// Global "button pressed" variables.
int8 C1_pressed = FALSE;
int8 C2_pressed = FALSE;
int8 C3_pressed = FALSE;
#define TICKS_BETWEEN_INTERRUPTS 5000 //5000 4/4=1 =1ms
#define INTERRUPT_OVERHEAD 35 //cycles wasted
#define TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))
/* Use XT mode, No Watch Dog, No Code Protect, No Power-up Timer */
#byte port_b=6 /* define the location of register port_b */
#byte port_c=7 /* define the location of register port_c */
const char LED_MAP[11] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xFF};
// 0 1 2 3 4 5 6 7 8 9 OFF
byte cnt,value;
byte i;
unsigned int32 result;
byte d1,d2,d3;
const char Column[4] = {0x80,0x40,0x20,0x10}; //Low bits(right,center,left)
static char Segment[4] = {0x24,0x24,0x24,0x24};
void display(void);
void setVoltage(void);
void CPU_SETUP(void);
void HTO7S(unsigned int32 Num);
// The buttons are read in this Timer0 (RTCC) isr.
#INT_RTCC
void rtcc_isr(void)
{
set_rtcc(RTCC_PRELOAD); // Reload the Timer.
if(button(PIN_C2, 0, 50, 2, C2, 1)){ //auto-repeat rate for button should be 2ms in 7-segment display
C2_pressed = TRUE;
}
if(button(PIN_C1, 0, 50, 2, C1, 1))
C1_PRESSED=TRUE;
if(button(PIN_C3, 0, 50, 2, C3, 1))
C3_PRESSED=TRUE;
}
#INT_TIMER1
void Timer1(void)
{
set_timer1(TMR1RESET);
display();
}
void main(){
CPU_SETUP();
value=0;
while(1){
result=0;
for (i=0;i<20;i++)
{
set_adc_channel(0);
delay_ms(1);
result=result+read_adc();
}
HTO7S(result/20);
delay_ms(200);
}
}
void CPU_SETUP()
{
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //interrupt to scan buttons
set_rtcc(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
setup_timer_2(T2_DIV_BY_1,TMR1RESET2,1); //interrupt to increement/decreement digits.
set_timer2(TMR1RESET2);
enable_interrupts(INT_TIMER2);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_64);
set_tris_a(1);
set_tris_b(0); //1 set port_b as outputs
set_tris_c(0x0F);
port_b = 0; // ZERO port_a & port_c
port_b=0x40;
cnt=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //no division interrupt for display
set_timer1(TMR1RESET); //65535-4965=60570
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
}
void display(void)
{
if(cnt>=4){
cnt=0;}
port_b=Segment[cnt];
port_c=Column[cnt];
cnt++;
}
#INT_TIMER2
void setVoltage(void)
{
//d1=d2=2;
d3=0;
while(C2_PRESSED)
{
//Segment[0]=LED_MAP[d1];
Segment[1]=LED_MAP[d2];
Segment[2]=LED_MAP[d3];
Segment[3]=0x40;
if(C1_PRESSED){ //increment digit by 1
d1=d1+1;
Segment[0]=d1;
C1_PRESSED=FALSE;
}
if(C3_PRESSED){ //decrement digit by 1
d1=d1-1;
Segment[0]=d1;
C3_PRESSED=FALSE;
}
if(button(PIN_C2, 0, 50, 2, C2, 1))
C2_PRESSED=TRUE;
else
C2_PRESSED=FALSE;
}
}
//--------------------------------------
// Convet HEX 2 byte to 7-Segment code
//--------------------------------------
void HTO7S(unsigned int32 Num)
{
unsigned int32 res;
Segment[0]=LED_MAP[30*Num/10230]; //calculating look-up value from LED_MAP array.
if (Segment[0]==0x40) //turning off 1st digit if 0
Segment[0]=0xFF; //dividing the three digits
res = 30*Num%10230;
Segment[1]=LED_MAP[10*res/10230];
res=10*res%10230;
Segment[2]=LED_MAP[10*res/10230];
res=10*res%10230;
Segment[3]=LED_MAP[10*res/10230];
}
|
|
|