View previous topic :: View next topic |
Author |
Message |
Namams
Joined: 01 Feb 2019 Posts: 9
|
|
Posted: Mon Feb 04, 2019 8:51 am |
|
|
I used a pic 16f819 and tried a simple code to check if the pic and LED were working which they were. I also checked the voltage on the pin and the LED orientation so I'm not sure what the problem could be. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Mon Feb 04, 2019 8:59 am |
|
|
One obvious thing. You _have_ got a pull-up on the MCLR pin?. The chip probably won't run without it. |
|
|
Namams
Joined: 01 Feb 2019 Posts: 9
|
|
Posted: Tue Feb 05, 2019 4:45 pm |
|
|
I understand that timer 0 is used to time the 2 second. Can someone just clarify why exactly timer 1 is needed in this code and also the signifcance of the "go" integer. Thank you. |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Wed Feb 06, 2019 4:25 am |
|
|
Timer1 is not used at all, nor Timer2. I just ticked them when I through the project wizard. Please just ignore them.
The code is spinning through the while loop an most of the time does nothing. Every 65ms Timer0 interrupt fires and sets the GO flag. When that happens, the code in the switch statement gets executed (if(GO){switch} ). It could be written as: if(GO == 1) .Only once every 65ms. That enables you to "count" the time, because you know exactly how much time elapsed by incrementing the counter and checking it against 31. |
|
|
Namams
Joined: 01 Feb 2019 Posts: 9
|
|
Posted: Wed Feb 06, 2019 6:32 am |
|
|
Hi, I made a few adjustments to the code and managed to get it to work using my PIC I've also added more switches and LEDs and the code seems to be working fine.
I now need to add another LED that would light up if switch one in pressed twice in 2 seconds (instead of if 2 different switches being pressed) but I can't seem to figure out a way to get it to work if anyone has any suggestions please let me know.
Current code:
Code: |
#include <16F819.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,MCLR,NOBROWNOUT
#use delay(clock=4000000)
#define SW1 PIN_B4
#define SW2 PIN_B5
#define SW3 PIN_B6
#define SW4 PIN_B7
#define SW5 PIN_B2
#define LED1 PIN_B0
#define LED2 PIN_B1
#define LED3 PIN_A0
#define LED4 PIN_A1
#define LED5 PIN_A2
#define LED6 PIN_A3
int SW1_PRESSED = 0;
int SW2_PRESSED = 0;
int SW3_PRESSED = 0;
int SW4_PRESSED = 0;
int SW5_PRESSED = 0;
int LIGHT_LED1 = 0;
int LIGHT_LED2 = 0;
int LIGHT_LED3 = 0;
int LIGHT_LED4 = 0;
int LIGHT_LED5 = 0;
int LIGHT_LED6 = 0;
int Counter1 = 0;
int Counter2 = 0;
int Counter3 = 0;
#INT_TIMER0
void TIMER0_ISR()
{
Counter1++;
Counter2++;
Counter3++;
if (!input(SW1))
{
SW1_PRESSED = 1;
}
else
{
SW1_PRESSED = 0;
}
if (!input(SW2))
{
SW2_PRESSED = 1;
}
else
{
SW2_PRESSED = 0;
}
if (!input(SW3))
{
SW3_PRESSED = 1;
}
else
{
SW3_PRESSED = 0;
}
if (!input(SW4))
{
SW4_PRESSED = 1;
}
else
{
SW4_PRESSED = 0;
}
if (!input(SW5))
{
SW5_PRESSED = 1;
}
else
{
SW5_PRESSED = 0;
}
if (SW1_pressed == 1)
{
LIGHT_LED1 = 1;
LIGHT_LED2 = 1;
Counter1 = 0;
}
if (Counter1 > 31)
{
LIGHT_LED1 = 0;
LIGHT_LED2 = 0;
}
if ((SW2_pressed == 1)& (Counter1 < 31))
{
LIGHT_LED1 = 2;
output_high(LED1);
}
if ((SW3_pressed == 1)& (Counter1 < 31))
{
LIGHT_LED2 = 2;
output_high(LED2);
}
if (SW4_pressed == 1)
{
LIGHT_LED3 = 1;
LIGHT_LED4 = 1;
Counter2 = 0;
}
if (Counter2 > 31)
{
LIGHT_LED3 = 0;
LIGHT_LED4 = 0;
}
if ((SW2_pressed == 1)& (Counter2 < 31))
{
LIGHT_LED3 = 2;
output_high(LED3);
}
if ((SW3_pressed == 1)& (Counter2 < 31))
{
LIGHT_LED4 = 2;
output_high(LED4);
}
if (SW5_pressed == 1)
{
LIGHT_LED5 = 1;
//LIGHT_LED6 = 1;
Counter3 = 0;
}
if (Counter3 > 31)
{
LIGHT_LED5 = 0;
LIGHT_LED6 = 0;
}
if ((SW2_pressed == 1)& (Counter3 < 31))
{
LIGHT_LED5 = 2;
output_high(LED5);
}
if ((SW3_pressed == 1)& (Counter3 < 31))
{
LIGHT_LED6 = 2;
output_high(LED6);
}
}
void main()
{
port_b_pullups(0xF0);
setup_timer_0(T0_INTERNAL | T0_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while (1)
{
}
} |
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Thu Feb 07, 2019 3:17 am |
|
|
Glad that you got it working. Just a couple of comments. Use indentations when you write, it is way more readable, especially if you start doing some nesting of if's or other things. And use some comments, after two days you will not know what you meant when you wrote something. I'm also not sure if it is a good idea to do everything inside your ISR. Anyway, here is the code to blink a LED if you press the same switch twice. I followed my own logic, sorry if it isn't a copy-paste solution.
Code: |
#include <main.h>
#define SW1 state, 4 // switch on PIN_B4 , but we are checking the "state" variable, which is a debounced input of PIN_B4
#define SW2 PIN_B5 //
#define SW3 PIN_B6
#define SW4 PIN_B7
#define LED1 PIN_B3 // LED on PIN_B3
#define LED2 PIN_B2
#define LED3 PIN_B1
#define LED4 PIN_B0
#define BITMASK 0b00110000;
char state = 0;
char PORTB_STATE;
int1 GO = 0;
int1 SW1_PRESSED = 0;
int1 SW2_PRESSED = 0;
int1 SW3_PRESSED = 0;
int1 SW4_PRESSED = 0;
int8 LIGHT_LED1 = 0; // LED1 state machine
#define WAIT_FIRST_PRESS 0 // states for LED1
#define WAIT_FIRST_RELEASE 1
#define WAIT_SECOND_PRESS 2
#define LED1_ON 3
int8 Counter1 = 0; // counter between two switches
// ****************************************************************************
unsigned char debounce(unsigned char sample)
// the debounce code below is from:
// https://www.compuphase.com/electronics/debouncing.htm
{
static unsigned char cnt0, cnt1;
unsigned char delta, toggle;
delta = sample ^ state;
cnt1 = cnt1 ^ cnt0;
cnt0 = ~cnt0;
cnt0 &= delta;
cnt1 &= delta;
toggle = cnt0 & cnt1;
state ^= toggle;
return state;
}
// ****************************************************************************
#INT_TIMER1
void TIMER1_isr(void) {
GO = 1;
}
#INT_TIMER2
void TIMER2_isr(void) {
delay_cycles(1);
PORTB_STATE = input_b(); // fixed_io on PIN_B3, otherwise this would turn the LED off
PORTB_STATE = PORTB_STATE & BITMASK; // leave only bits 4 and 5 as they were, all other 0
debounce(PORTB_STATE); // check for a change every 6ms and wait for the input to settle
}
#INT_TIMER0
void TIMER0_isr(void) {
}
void main() {
// 18f252 , 20MHz crystal. Comment this out and uncoment for your chip
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT); //51,2 us overflow
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //52,4 ms overflow
setup_timer_2(T2_DIV_BY_16,117,16); //377 us overflow, 6,0 ms interrupt
// 16f819, 4MHz internal
/*
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_BIT); //65,5 ms overflow
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //65,5 ms overflow
setup_timer_2(T2_DIV_BY_16,46,8); //752 us overflow, 6,0 ms interrupt
// timings are a bit different, but close enough
*/
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
// enable_interrupts(INT_TIMER0); // Timer0 interrupt not used
enable_interrupts(GLOBAL);
port_b_pullups(TRUE);
output_high(LED1); // turn off LED
delay_ms(50); // make sure state variable settles to 0bxxx1xxxx (switch on PIN_B4) open
while(TRUE){
if(GO){
GO = 0;
// ******************** check LED1 condition **********************************
switch (LIGHT_LED1){
case WAIT_FIRST_PRESS:{ // nothing is pressed, we are waiting for SW1 to be pressed
if(bit_test(SW1) == 0){ // we are checking the "state" variable, which is a debounced input of PIN_B4
LIGHT_LED1 = WAIT_FIRST_RELEASE; // switch pressed, wait till it is also released
}
break;
}
case WAIT_FIRST_RELEASE:{ //we are waiting for SW1 to be released
if(bit_test(SW1)){
LIGHT_LED1 = WAIT_SECOND_PRESS;
Counter1 = 0; // button was pressed and released. Now we go wait for two seconds for another press.
}
break;
}
case WAIT_SECOND_PRESS:{ // wait 2 seconds for a second press
Counter1++;
if(Counter1 > 31){
LIGHT_LED1 = WAIT_FIRST_PRESS;
break; // if more than two seconds passed, start over
}
if(bit_test(SW1) == 0){ // if under two sec and switch closed, turn on LED
LIGHT_LED1 = LED1_ON;
Counter1 = 0;
output_low(LED1); // turn on the led and go wait for the switch to be released
}
break;
}
case LED1_ON:{
Counter1++;
if(Counter1 > 8){
Counter1 = 8; // prevent counter to owerflow back to 0
output_high(LED1); // turn off the LED after a while
if(bit_test(SW1)){
LIGHT_LED1 = WAIT_FIRST_PRESS; // and make sure the switch is released before starting over
}
}
break;
}
} // switch LIGHT_LED1 brace
// ************************ END LED1 check ************************************
} // if(GO) brace
} // while brace
} // main brace
|
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Thu Feb 07, 2019 3:20 am |
|
|
main.h
Code: |
#include <18F252.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#device ICD=TRUE
#use delay(crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=RS232,errors)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3, force_HW)
#use fixed_io(b_outputs=PIN_B3) // B3 is output at all time
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Thu Feb 07, 2019 6:39 am |
|
|
re:
#use fixed_io(b_outputs=PIN_B3) // B3 is output at all time
...
be very,very careful when using 'fixed_io' !! sooner AND later you'll get 'stung' by no having the correct port settings !
for 99.99999999% of all PIC programs you're 100% OK using 'standard_IO', the default for CCS. fast_io is usually ONLY for 'time critical' applications, say a custom peripheral or 'bitbanging' a propriatory communications network.
re:
PORTB_STATE = input_b();
you should try
.......=input_state(xxx);
it returns state of th epin without changing the tris reg.
Jay |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Thu Feb 07, 2019 7:45 am |
|
|
Exactly what I was looking for :-)
Thanks |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Thu Feb 07, 2019 8:22 am |
|
|
hope it works..
one day I should actually READ the CCS manual which 'magically' opens up when you press F11 ifyour project is open. Forsome silly reson I prefer to thumbthrough the spiral bound manual though..
Jay |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Thu Feb 07, 2019 11:44 am |
|
|
I was actually a bit too quick with my answer before. I do not need a state of one single pin, but the state of the whole port. If I had 8 switches, there would be no problem, they'd be inputs anyway, if not sooner after input_x(). Is there a way to scan all 8 bits of a port, one bit at a time in a loop and write the resulting states one by one to a variable?
Basically, something like:
variable, 0 = port_x, 0 and loop from 0 to 7
BTW, f11 doesn't do anything, but I was looking through help file. I also have a printed manual here, my kid was more than eager to print it and bind it. Not all the pages are in correct order, but ... :-) |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Thu Feb 07, 2019 12:02 pm |
|
|
sure,sounds OK... you should be able to use the 'bit_test()' function as well.
others have probably done that.
hmm F11 draws a blank?....
I currently use MPLAB 8v92 to access CCS compiler and to program PICs using a PICkit3. With a project open, pressing F11 opens up the CCS Manual. Actually has for years. |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 304
|
|
Posted: Thu Feb 07, 2019 12:28 pm |
|
|
When using the CCS IDE you press F1 for help to get the manual. |
|
|
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Thu Feb 07, 2019 1:16 pm |
|
|
Using MPLAB X here... F11 builds :D
Oh well, I have the CCS manual pinned to my start menu for easy access anyway. |
|
|
Namams
Joined: 01 Feb 2019 Posts: 9
|
|
Posted: Mon Feb 18, 2019 7:08 am |
|
|
Is there a way I can check the state of an output pin? for example say I wanted to execute an if function and the condition was that the output of pin b1 was set to low how would I code that? |
|
|
|