I'm new to microcontrollers and picked out a PIC10f204. I am using MPLAB XIDE with the free XC8 C compiler.
I'm trying to slowly learn right now. All i am trying to do is set GPIO bit 0, which is the GP0 pin out, to out put high.
So far my code looks like this but I am not measuring 5V from the pin GP0 or any of the other GPIO pins, except GP3.
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
// CONFIG
#pragma config WDTE = OFF // Watchdog Timer (WDT disabled)
#pragma config CP = OFF // Code Protect (Code protection off)
#pragma config MCLRE = OFF // Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)
int main(void) {
OSCCAL= 0x00;
TRISGPIO = 0x00;
GPIO= 0xFF;
return 0; // we should never reach this
}
Any help would be much appreciated.
Thanks!
A couple changes might help:
1) Try adding an infinite loop in your code. The program on a microcontroller should follow a general structure of initialization functions followed by an infinite loop.
2) Looking at the datasheet for the PIC10F204, it says that pin 3 is input only. Try modifying as follows: TRISGPIO = 0x08;
I modified your code below to illustrate this. Hopefully this works for you.
int main(void) {
// PIC Initializations should go here
OSCCAL= 0x00;
CMCON0 = 0x51;
TRISGPIO = 0x08;
GPIO= 0xFF;
while(1) {
// Program main loop (should never end)
}
return 0; // we should never reach this
}
Related
I have been attempting to set up the I2C on a system which uses the SAM L10 MCU. I have been able to build my project on MPLAB X as a standalone project without having to use MPLAB Harmony v3 code configurator. My problem is I can't seem to get the interrupt handlers to be mapped correctly.
Here are the references I am using:
https://github.com/Microchip-MPLAB-Harmony/csp_apps_sam_l10_l11/tree/master/apps/sercom/i2c/master/i2c_eeprom
and
https://microchipdeveloper.com/32arm:samd21-code-gcc-nvic-example
In both cases, there seems to be a table which assigns function pointers for the interrupt handlers, called exception_table. I do not know the correct way to incorporate this in my code, in fact, I don't understand how this code actually gets executed as it is simply assigning the function pointers.
Here is what I have for my code:
init.c
#include <xc.h>
#include "peripheral/clock/plib_clock.h"
#include "peripheral/nvic/plib_nvic.h"
#include "peripheral/sercom/plib_sercom0_i2c_master.h"
#pragma config NVMCTRL_NSULCK = 0x7
#pragma config BOD33_LEVEL = 0x6
#pragma config BOD33_DIS = CLEAR
#pragma config BOD33_ACTION = 0x1
#pragma config WDT_RUNSTDBY = CLEAR
#pragma config WDT_ENABLE = SET
#pragma config WDT_ALWAYSON = CLEAR
#pragma config WDT_PER = 0x9
#pragma config WDT_WINDOW = 0xB
#pragma config WDT_EWOFFSET = 0xB
#pragma config WDT_WEN = CLEAR
#pragma config BOD33_HYST = CLEAR
void port_init (void)
{
/* Configure SERCOM0 I2C on PA22 and PA23, Peripheral function C */
PORT_REGS->GROUP[0].PORT_PINCFG[22] = 0x1;
PORT_REGS->GROUP[0].PORT_PINCFG[23] = 0x1;
PORT_REGS->GROUP[0].PORT_PMUX[11] = 0x22;
/* Configure PA25 as an output driven high */
PORT_REGS->GROUP[0].PORT_DIR = 0x02000000;
PORT_REGS->GROUP[0].PORT_OUT = 0x02000000;
PORT_REGS->GROUP[0].PORT_PINCFG[27] = 0x0;
}
void sys_initialise (void)
{
CLOCK_Initialize ();
port_init ();
SERCOM0_I2C_Initialize ();
NVIC_Initialize ();
}
main.c
#include <xc.h>
#include "init.h"
#include "peripheral/sercom/plib_sercom0_i2c_master.h"
void main (void)
{
sys_initialise ();
uint8_t reg[1];
reg[0] = 0xD0;
SERCOM0_I2C_Write (0x76, ®[0], 2);
}
I used the GPIO for my debugging. I thought setting up the NVIC would be enough but it only enables the interrupt themselves, the interrupt handler is still not mapped. I can see it because from my debugging the handler never gets called when I try to send something over I2C. I can also see the I2C work correctly for sending the first part of the transaction, which is the device address up to the ACK bit. From this point on, I can see on the scope that the clock is held low but the SDA comes back to high. I believe it is because the interrupt handler SERCOM0_I2C_InterruptHandler from https://github.com/Microchip-MPLAB-Harmony/csp_apps_sam_l10_l11/blob/master/apps/sercom/i2c/master/i2c_eeprom/firmware/src/config/sam_l10_xpro/peripheral/sercom/i2c_master/plib_sercom0_i2c_master.c does not get called, as this is responsible for sending the rest of the data.
I found the answer to this in the user guide for the xc32 compiler which can be accessed here: https://ww1.microchip.com/downloads/en/DeviceDoc/XC32_PICC_UG_DS50002895A.pdf
I was missing the call to NVIC_SetVector() - section 14.3 shows how to associate the interrupt handler with an exception.
I am developing a simple program to run a buzzer in AVR on a Teensy 2.0 (ATMEGA32u4) and I am having great difficulty getting the PWM output to work. The PWM output is on PB6 and I can test it digitally so I am not worried about the hardware setup of the buzzer.
Eventually, the PWM will have a 50% duty cycle and the frequency will modulate, however, I am more concerned I am not getting any output at this point.
I have tried several different PWM setups and even have a second timer running to complete other tasks.
Here is my setup and program skeleton:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
void button_handler(void);
void setup(void)
{
cli(); // Disable interrupts
// Set sysclk to 16 MHz
CLKPR = (1<<CLKPCE); // Prescaler change enable
CLKPR = 0x00; // Set prescaler to zero
DDRB = (1<<DDB6); // configure PORT B6 (buzzer) as output
// initliase timer1
// Fast PWM, TOP = OCR1A, Update OCR1B at TOP, TOV1 flag set on TOP
// Clear OC1B on compare match, set OC1B at TOP
// clkI/O/1 (No prescaling)
TCCR1A = (1<<COM1B1)|(1<<WGM11)|(1<<WGM10);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS10);
OCR1A = 1023; // Setup PWM Registers
OCR1B = 511; // 50% duty cycle
sei(); // Enable interrupts
}
int main(void)
{
setup(); // initialise device
for (;;)
{
// runs led blinking on PORTD, removed for simplicity
}
}
Really struggling to see where I am going wrong so any help would be much appreciated!
Finally managed a fix coming back after a few months, a simple clean fixed the issue.
I have 2 questions.
The first: I have a problem in the behavior of this code; when I run it in Proteus the program make flasher "repeat the code in the main function"
what should I do?
This is the code:
#include <p18f452.h>
#include <delays.h>
#include <io.h>
void main ()
{
TRISC=0x00;
PORTC=0xff;
Delay1KTCYx(900);
PORTC=0x00;
Delay1KTCYx(900);
while(1)
{
}
}
The second question: what is the proper delay function I can use? and how can I measure the delay time?
Is the watchdog disabled in simulation ? If it is enabled it will cause the repetition of the program.
Try adding this line after the includes.
#pragma config WDT = OFF
You only have code to generate one flash. Move the flash and delays into the loop:
for(;;)
{
PORTC = 0xff;
Delay1KTCYx(900);
PORTC = 0x00;
Delay1KTCYx(900);
}
Measuring roughly can be made manually by timing N flashes with a stopwatch. It's of course easier to use a measurement intrument (an oscilloscope is nice for this) if you have it.
Also, since your duty cycle is 50%, you can simplify the code:
PORTC = 0;
for (;;)
{
PORTC = ~PORTC;
Delay1KTCYx(900);
}
This uses bitwise not (~) to invert the bits of PORTC, which will make them toggle from one to zero and vice versa. Setting the entire port to 0 before the loop makes sure all pins are at a known state.
I'm pretty new to PIC programming and I'm trying to use C (compiled with Microchip's XC8 Free in MPLABX) to make a simple "Input to Output" program.
The problem I'm having is that the RA2, RA3 and RA5 input pins are just not working when programming in C.
It's probably not a hardware problem, because when programming in Ladder those pins work just fine.
I've searched around on the internet for a while and couldn't find anyone with the same problem yet.
The program I'm trying to burn onto the PIC is as follows:
#define _XTAL_FREQ 20000000
#include <xc.h>
// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#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)
//END CONFIG
int main()
{
TRISB = 0x00;
TRISE = 0x00;
TRISC = 0x00;
TRISD = 0xFF;
TRISA = \
_TRISA_TRISA2_MASK |\
_TRISA_TRISA3_MASK |\
_TRISA_TRISA4_MASK |\
_TRISA_TRISA5_MASK;
PORTD = 0x00;
PORTA = 0x00;
PORTB = 0x00;
PORTE = 0x00;
PORTC = 0x00;
while(1){
PORTB = PORTA;
}
return 0;
}
I do get an output on PORTB if I set RA4 to HIGH, but not for RA2, RA3 nor RA5. I believe this might be a problem with the configuration bits or something, but I'm not sure.
Hardware being used:
Microchip PIC16F887
FLEXiS Plus Board (sorry no english manual, but in page 8 and 9 there are board schematics)
Software being used:
Microchip MPLABX IDE
TinyBootloader
I think the problem is that those specific pins are also Analog Inputs for the ADC Module, you have to configure them to be digital I/O to use them. Try setting ANSEL = 0x00 at the beginning of your program.
You can see in the datasheet that the default value of ANSEL on POR is 0xFF so all analog pins are configured as analog inputs by default.
To use pins for analog input, you should set the relevant bits in both the ANSEL and TRISx registers.
I wrote a program for the PIC 16f690 microcontroller after noticing my programs seemed to be exiting an endless loop.
There are LEDs on pins 3,4,5 of PORTC.
#include <xc.h>
#define _XTAL_FREQ 4000000
void main(void) {
TRISC = 0x00;
PORTC = 0b00111000;
while (1)
{
__delay_ms(1000);
PORTC = 0x00;
}
}
As far as I understand, the LEDS should be on for ~1sec, and then be off forever. Instead they keep blinking every second.
I wrote this in MPLABX and programmed using PICkit3 and C8 compiler.
You are likely being bitten by the watchdog. Disable the watchdog for your tests or clear it before it reset the MCU.
I had the same issue but in place of leds, I was using serial communications. while(1) was not really a loop forever and execute the stuff between brackets.
As soon as I disabled the watchdog, only the stuff inside the brackets was called after the first iteration.
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT enabled)
I was also observing trash after every uart packet and that went away with the watchdog disabled.
FYI pic 16f1708.
This caused some erratic behavior since the uart initialization functions, IO setup, and oscillator divider were called every loop iteration.