I'm not new to programming or C, but I am very new to chip programming in particular and I'm having a lot of trouble finding and deciphering documentation.
To be specific, I am using MPLab X IDE in conjunction with the XC8 compiler. My chip is a PIC12F1501. My intent (for now) is to gently pulse an LED, but eventually it will be adapted to drive a speaker with a sine wave. Pretty sure my circuit is good as I can make an LED blink on and off with a digital output.
Now, I understand how to set the TRIS register so that the right legs are output or input as required. I know how to use ANSEL to set these pins into analog mode. What I cannot seem to fathom is what command or combination of commands I need to use to actually write an analog value to a pin. I've used the latch (LAT) to set a digital output, but I can't see how to do the same thing with an analog value.
From the data sheet for the chip I get the vague idea that I'm supposed to set the value of some other register representing the DAC to determine the level of voltage output, and then latch to 1 just as you would for digital output, but I'm not used to reading these things. I've tried a number of register names that are hinted in the documentation for the DAC but none of them compile.
I've tried snippets of code for other chips in the same approximate family and none of them compile either.
Can someone share a brief snippet demonstrating how analog output works in the PIC12F1501?
In the specification sheet for the PIC12(L)F1501, you will find the required registers described in chapter 16 (pages 124 - 126). In short summary they are DAC1CON0 and DAC1CON1. You set your desired value with the DAC1CON1 register and enable/configure with the DAC1CON0 register.
One thing to note is that the DAC is not meant to drive an external load and probably wont work with your LED attached unless you have an external buffer.
// With 5V and 0V Positive/Negative references, outputs 3.125V
// (See manual equation 16-1).
DAC1CON1 = 20;
// Enable the DAC and output to both DACOUT pins using VDD as positive
// reference (see manual register 16-1).
DAC1CON0 = 0b10110000;
// Note that most chips also have utility structs in the MC8 headers so
// you can also set the bits individually as follows:
DAC1CON0bits.DACOE1 = 1;
DAC1CON0bits.DACOE2 = 1;
DAC1CON0bits.DACEN = 1;
The Microchip supplied header file does not define DAC1CON0 or DAC1CON1 only DACCON0 and DACCON1.
This code may build for you:
/*
* File: main.c
* Target: PIC12F1501
* Compiler: XC8 v1.45
* IDE: MPLABX v4.05
* Author: dan1138
*
*
* PIC12F1501
* +---------------:_:---------------+
* PWR -> : 1 VDD VSS 8 : <- GND
* <> : 2 RA5 DACOUT1/PGD/RA0 7 : <> ICD_PGD
* <> : 3 RA4 PGC/RA1 6 : <> ICD_PGC
* ICD_MCLR -> : 4 RA3/MCLR DACOUT2/INT/RA2 5 : <> DAC-OUTPUT
* +---------------------------------+
* DIP-8
*
* Created on July 25, 2018, 7:20 PM
*/
#pragma config FOSC = INTOSC /* Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin) */
#pragma config WDTE = OFF /* Watchdog Timer Enable (WDT disabled) */
#pragma config PWRTE = OFF /* Power-up Timer Enable (PWRT disabled) */
#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 BOREN = OFF /* Brown-out Reset Enable (Brown-out Reset disabled) */
#pragma config CLKOUTEN = OFF /* Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) */
#pragma config WRT = OFF /* Flash Memory Self-Write Protection (Write protection off) */
#pragma config STVREN = ON /* Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) */
#pragma config BORV = LO /* Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) */
#pragma config LPBOR = OFF /* Low-Power Brown Out Reset (Low-Power BOR is disabled) */
#pragma config LVP = OFF /* Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) */
#include <xc.h>
void main(void)
{
DACCON0 = 0x90; /* DAC drives DACOUT2 */
for(;;)
{
/* generate a 5-bit sawtooth outout */
DACCON1 = (DACCON1 + 1u) & 0x1Fu;
}
}
Your PIC12F1501 also has got 4 PWM channels. You can very easily use these PWMs as analog output when you put a RC-Filter behind the pin. That will give you a resolution of up to 10 Bit.
Related
I recently started in a fresh company where the programer that did the PIC32 programming is now gone and I do need to troubleshoot his uC-Code.
He disliked the Microchip Harmony Configurator/Framework and thus he is only using the Peripheral Library of the Harmony Framework to do coding (That means he used alot of PLIB_*-functions in his code, taken from examples).
For this he extraced the sys_devcon.c and sys_devcon.h files from framework/system/devcon/src and copied that file to the project's source.
Now my Problem:
Below you see the device.cfg. The Pins OSC1 and OSC2 are connected to the primary oscillator (4MHz). We already confirmed that the oscillator is working correctly by testing it with a LeCroy Teledyne (shows 4MHz).
With the Config given by the file the SystemClock (SYSCLK) is derived by the SYSPLL. Since my IDIV is 1, my MULT is 18 and my ODIV is 1, I expect the SYSCLK to run at 72MHz (4/1*18/1=72).
The PBDIV is set to DIV_2 (so PBCLK=SYSCLK/2 -> 36MHz). The REFCLK is expected to run at 6.4MHz.
HOWEVER:
The measured PBCLK shows 18MHz, the measured REFCLK(SYSPLL as F_REFIN, shows 3.2MHz which means the SYSCLK only runs 36MHz (not expected 72MHz). But taken the config into account everthing should run twice as fast. Im unable to locate the problem why the SYSCLK runs at half speed.
I troubleshooted every single PLIB_OSC*(including PLIB_OSC_SLEW*) function inside the code and havent found a single issue (only 5 lines to use some sort of PLIB_OSC* functions). Maybe someone got some ideas/hints to troubleshoot. It's also not clear if the SYSCLK is actually halved or if there is some divider after the SYSPLL (in between REFCLK and PBCLK). Is there a way i can measure the SYSCLK?
uC: PIC32MX174F256B
XC-Version: V2.10
Harmony: V2.05.01 (only PLIB is used)
MPLAB X IDE: v4.20
#ifndef PIC32MX174F256B_CONFIG_HEADER
#define PIC32MX174F256B_CONFIG_HEADER
#ifdef __cplusplus
extern "C" {
#endif
/* PIC32MX174F256B Configuration Bit Settings */
// DEVCFG3
// USERID = No Setting
// Alternate I/O Select for I2C1 (I2C1 uses the SDA1/SCL1 pins)
#pragma config AI2C1 = OFF
// Alternate I/O Select for I2C2 (I2C2 uses the SDA2/SCL2 pins)
#pragma config AI2C2 = OFF
#pragma config PMDL1WAY = OFF // Peripheral Module Enable Configuration
#pragma config IOL1WAY = OFF // Peripheral Pin Select Configuration (Allow reconfigurations)
// DEVCFG2
#pragma config FPLLIDIV = DIV_1 // PLL Input Divider (1x Divider)
#pragma config FPLLMUL = MUL_18 // PLL Multiplier (18x Multiplier)
#pragma config FPLLICLK = PLL_POSC // System PLL Input Clock Selection (POSC is input to the System PLL)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)
#pragma config BOREN = ON // Brown-Out Reset (BOR) Enable (Enable BOR)
#pragma config DSBOREN = ON // Deep Sleep BOR Enable (Enable ZPBOR during Deep Sleep Mode)
#pragma config DSWDTPS = DSPS7 // Deep Sleep Watchdog Timer Postscaler (1:2^11)
#pragma config DSWDTOSC = LPRC // Deep Sleep WDT Reference Clock Selection (Select LPRC as
// DSWDT Reference clock)
#pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (Disable DSWDT during
// Deep Sleep Mode)
#pragma config FDSEN = ON // Deep Sleep Enable (Enable DSEN bit in DSCON)
// DEVCFG1
#pragma config FNOSC = SPLL // Oscillator Selection Bits (Primary Osc (HS,EC, XT))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
// value can also be adjusted in module sys_system from libpic32mx174f256b
#pragma config FPBDIV = DIV_2 // Peripheral Clock Divisor
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch
// Disable, FSCM Disabled)
#pragma config WDTPS = PS1 // Watchdog Timer Postscaler (1:1)
#pragma config WDTSPGM = ON // Watchdog Timer Stop During Flash Programming (Watchdog
// Timer stops during Flash programming)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window Size is 25%)
// DEVCFG0
#pragma config JTAGEN = OFF // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config SMCLR = MCLR_NORM // Soft Master Clear Enable (MCLR pin generates a normal system Reset)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
I maybe found the issue:
The Device data sheet states:
‘3’ wait states is required for 0-72 MHz operation
However, the sys_devcon.c only defines 0-2 wait states. But not only that, it will actually define no wait states, since #if defined(PLIB_PCACHE_ExistsWaitState) is not defined.
#if defined(PLIB_PCACHE_ExistsWaitState)
if (PLIB_PCACHE_ExistsWaitState(PCACHE_ID_0))
{
int ws; /* number of wait states */
if (sysclk <= 30000000)
ws = 0;
else if (sysclk <= 60000000)
ws = 1;
else
ws = 2;
/* Interrupts must be disabled when changing wait states */
int_flag = (bool)(PLIB_INT_GetStateAndDisable( INT_ID_0 ) & 0x01);
PLIB_PCACHE_WaitStateSet(PCACHE_ID_0, ws);
if (int_flag)
{
PLIB_INT_Enable(INT_ID_0);
int_flag = false;
}
}
#endif // defined(PLIB_PCACHE_ExistsWaitState)
However,
#if defined(PLIB_PCACHE_ExistsWaitState)
is not defined, thus it will never assign wait states.
Do I simply define it with #define PLIB_PCACHE_ExistsWaitState or will I run into an error?
I finally solved the issue by myself.
It was simply my lack of knowledge. I found the crucial information in 2 seperate data sheets.
One was the "PIC32MX1XX/2XX 28/44-PIN XLP FAMILY Data Sheet" on page 318, which states that the maximum SPICLK must not exceed 25MHz (I believe .
The second crucial information was the calculation of the BaudRate.
I thought that the BaudRate equals the selected PBCLK (so when I have a SYSCLK of 72MHz and the PBCLK is SYSCLK=PBCLK/2 => 36MHz, the BaudRate is also set at 36MHz).
But at page 23-29 at "PIC32 FRM Section 23. Serial Peripheral Interface (SPI)" there is the formula
F_SCK = F_PB / ( 2 ⋅ ( SPIxBRG + 1 ))
Strange question.
I have two PICDEM FS USB Demo Boards from Microchip (with the PIC18F45K50 chip on them). I ordered a second one because the first was acting really strange and I figured it was defective. But the second one does it too.
The behavior is that it seems like the clock on the chip only runs when I touch the OSC1 pin as though my body is somehow acting as the ground for the chip. I have a male-to-male header wire stuck in the OSC1 header port and when I pinch it, the LEDs blink as though the system clock is running.
If I take my fingers off, it's like the system clock stops. I have a few different programs that flash based on time, pressing the buttons, or turning the potentiometer. But they all have the same behavior: unless I pinch the wire, nothing happens, like the system clock is stopped. Note that connecting the OSC1 pin to the GND pin does accomplish the same thing, so my hypothesis about my body acting as the ground doesn't seem to make much sense.
I can't find anything about this in the user guide for the board, or any help threads mentioning the same behavior.
My only guess is that maybe it's something about the configuration flags I'm using in my programs, but from what I understand they look fine:
// PIC18F45K50 Configuration Bit Settings
// CONFIG1L
#pragma config PLLSEL = PLL4X // PLL Selection (4x clock multiplier)
#pragma config CFGPLLEN = OFF // PLL Enable Configuration bit (PLL Disabled (firmware controlled))
#pragma config CPUDIV = NOCLKDIV// CPU System Clock Postscaler (CPU uses system clock (no divide))
#pragma config LS48MHZ = SYS24X4// Low Speed USB mode with 48 MHz system clock (System clock at 24 MHz, USB clock divider is set to 4)
// CONFIG1H
#pragma config FOSC = HSH // Oscillator Selection (HS oscillator, high power 16MHz to 25MHz)
#pragma config PCLKEN = ON // Primary Oscillator Shutdown (Primary oscillator enabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config nPWRTEN = ON // Power-up Timer Enable (Power up timer enabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable (BOR enabled in hardware (SBOREN is ignored))
#pragma config BORV = 190 // Brown-out Reset Voltage (BOR set to 1.9V nominal)
#pragma config nLPBOR = OFF // Low-Power Brown-out Reset (Low-Power Brown-out Reset disabled)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (WDT disabled in hardware (SWDTEN ignored))
#pragma config WDTPS = 32768 // Watchdog Timer Postscaler (1:32768)
// CONFIG3H
#pragma config CCP2MX = RC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config T3CMX = RC0 // Timer3 Clock Input MUX bit (T3CKI function is on RC0)
#pragma config SDOMX = RB3 // SDO Output MUX bit (SDO function is on RB3)
#pragma config MCLRE = ON // Master Clear Reset Pin Enable (MCLR pin enabled; RE3 input disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled if MCLRE is also 1)
#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming Port Enable (ICPORT disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled)
// CONFIG5L
#pragma config CP0 = OFF // Block 0 Code Protect (Block 0 is not code-protected)
#pragma config CP1 = OFF // Block 1 Code Protect (Block 1 is not code-protected)
#pragma config CP2 = OFF // Block 2 Code Protect (Block 2 is not code-protected)
#pragma config CP3 = OFF // Block 3 Code Protect (Block 3 is not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protect (Boot block is not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protect (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Block 0 Write Protect (Block 0 (0800-1FFFh) is not write-protected)
#pragma config WRT1 = OFF // Block 1 Write Protect (Block 1 (2000-3FFFh) is not write-protected)
#pragma config WRT2 = OFF // Block 2 Write Protect (Block 2 (04000-5FFFh) is not write-protected)
#pragma config WRT3 = OFF // Block 3 Write Protect (Block 3 (06000-7FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Registers Write Protect (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protect (Boot block (0000-7FFh) is not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protect (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Block 0 Table Read Protect (Block 0 is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Block 1 Table Read Protect (Block 1 is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Block 2 Table Read Protect (Block 2 is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Block 3 Table Read Protect (Block 3 is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protect (Boot block is not protected from table reads executed in other blocks)
Any help would be appreciated.
It turned out to be just as I suspected, one of the configuration flags was wrong. Changing the setting of FOSC fixed the problem. The new line is:
#pragma config FOSC = INTOSCIO // Oscillator Selection (Internal oscillator)
Being new to PIC programming I'm not sure what the external oscillator was that it was expecting but somehow it ended up being me.
If it was working at all the board probably has an external oscillator on it and you must have selected the wrong gain setting for it. That is the same setting but if you select eg XT for an oscillator which needs HS then it will be marginal and start working only when you touch it and in doing so change the load capacitance.
This is a simple program to on/off led in XC8 (Microchip):
1) This code work :
#include <xc.h>
#define _XTAL_FREQ 4000000
#pragma config FOSC = HS // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Disable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void main()
{
TRISB0=1;
TRISB4=0;
if (RB0==1)
{
RB4 = 1;
}
else
{
RB4 = 0;
}
}
Switch Connected to portb RB0
2) This code doesn't work :
#include <xc.h> // Librería XC8
#define _XTAL_FREQ 4000000 // Indicamos a que frecuencia de reloj esta funcionando el micro
// PIC16F648A Configuration Bit Settings
#pragma config FOSC = HS // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
void main()
{
TRISA0=1;
TRISB4=0;
if (RA0==1)
{
RB4 = 1;
}
else
{
RB4 = 0;
}
}
Switch Connected to port RA0
Why I can on led If I get port B but not in port A ?
Best Regards.
The ANSEL should be set correctly or the ADC might override it and make it an input as commented on above.
But to set PORT pin outputs you generally
use the LATCH register. RB4 is what you read when the pin is configured as a digital input. LATB4 is the output latch.
LATB4 = X;
where X is 1 or 0
I interfaced RFID with PIC 18f4550, I tried displaying values of RCREG on LCD, but only got a box displayed. What could be the problem?
I am using MPLAB X with the XC8 compiler
// Program to interface RFID module using EUSART in PIC18F2550
#include <p18f4550.h>
#include <stdio.h>
/* _CPUDIV_OSC1_PLL2_1L, // Divide clock by 2
_FOSC_HS_1H, // Select High Speed (HS) oscillator
_WDT_OFF_2H, // Watchdog Timer off
MCLRE_ON_3H // Master Clear on
*/
// CONFIG1L
#pragma config PLLDIV = 1 // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1 // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
// CONFIG1H
#pragma config FOSC = INTOSC_HS // Oscillator Selection bits (Internal oscillator, HS oscillator used by USB (INTHS))
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = ON // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF // USB Voltage Regulator Enable bit (USB voltage regulator disabled)
// CONFIG2H
#pragma config WDT = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
//#pragma config CCP2MX = ON // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming Port (ICPORT) Enable bit (ICPORT disabled)
// #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
//#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
//#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
//#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
//#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
//#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
//#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
//#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
//#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF
// Program to interface RFID module using EUSART in PIC18F4550
// Configuration bits
/* _CPUDIV_OSC1_PLL2_1L, // Divide clock by 2
_FOSC_HS_1H, // Select High Speed (HS) oscillator
_WDT_OFF_2H, // Watchdog Timer off
MCLRE_ON_3H // Master Clear on
*/
#define FREQ 20000000
#define baud 9600
#define spbrg_value 19
#define rs LATAbits.LATA0
#define rw LATAbits.LATA1
#define en LATAbits.LATA2
#define lcdport LATB
unsigned char rx_data();
void lcd_ini();
void lcdcmd(unsigned char);
void lcddata(unsigned char);
unsigned char data[]="Unique ID No.";
unsigned char card_id[12];
unsigned int i=0,j=0,pos;
void Delay_ms(int t)
{
int i;
int j;
for (i=0;i<t;i++)
for(j=0;j<100;j++);
}
void main()
{
TRISB=0; // Set Port B as output port
LATB=0;
TRISA=0;
LATA=0;
SPBRG=spbrg_value; // Fill SPBRG register to set the baud rate
RCSTAbits.SPEN=1; // To activate serial port (Tx and Rx pins)
RCSTAbits.CREN=1; // To enable continuous reception
PIE1bits.RCIE=1; // To enable the Reception (Rx) Interrupt
INTCONbits.GIE=1;
INTCONbits.PEIE=1;
lcd_ini(); // LCD initialization
while(data[i]!='\0')
{
//lcddata(data[i]); // To send characters one by one from 'data' array
i++;
}
while(1)
{
i=0;
while(PIR1bits.RCIF ==0);
}
}
void interrupt ISR()
{
i=0;
unsigned char c = 'P';
lcddata(c);
while(i<12)
{
card_id[i]=RCREG;
lcddata(card_id[i]);
i++;
}
card_id[11]='\0';
/*while(i<12)
{
char cc=card_id[i];
lcddata(cc);
i++;// Print the 12 byte received
}}
while(data[i]!='\0'){
lcddata(data[i]);
i++;
}*/
}
void lcd_ini()
{
lcdcmd(0x38); // Configure the LCD in 8-bit mode, 2 line and 5x7 font
lcdcmd(0x0C); // Display On and Cursor Off
lcdcmd(0x01); // Clear display screen
lcdcmd(0x06); // Increment cursor
lcdcmd(0x80); // Set cursor position to 1st line, 1st column
}
void lcdcmd(unsigned char cmdout)
{
lcdport=cmdout; //Send command to lcdport=PORTB
rs=0;
rw=0;
en=1;
Delay_ms(10);
en=0;
}
void lcddata(unsigned char dataout)
{
lcdport=dataout; //Send data to lcdport=PORTB
rs=1;
rw=0;
en=1;
Delay_ms(10);
en=0;
}
I keep getting an error saying illegal conversion of pointer to string on the line where i assign card_id[i] the value of RCREG and it seems that RCREG is returning the address
The watchdog timer is enabled #pragma config WDT = ON but never cleared. Periodically call ClrWdt(); or disable it, otherwise the program will reset every time the watchdog timer expires.
Not causing a problem but worth mentioning, with XC8 Microchip recommends using #include <xc.h> which will make including the processor specific header unnecessary.
The character that is in RCREG is being moved into all 12 elements of card_id, was that really intended?
The UART will assert an interrupt and set RCIF each time a character is received. Reading RCREG clears the flag. It's generally not a good idea to do tasks (especially ones with delays) while servicing the interrupt because incoming characters can be missed. Consider establishing a circular queue and doing something like this:
void interrupt ISR()
{
while(PIR1bits.RC1IF){
queue1[q1tail] = RCREG1;
if(++q1tail >= Q_SIZE)
q1tail = 0;
}
}
Then in the main forever loop check the queue. When something comes in (q1tail != q1head) process it as necessary and pop it off the queue (increment q1head).
It's also a good idea to check for overrun and framing errors. It can be done when checking the queue pointers:
if (RCSTA1bits.OERR || RCSTA1bits.FERR)
{
RCSTA1bits.CREN = 0;
Nop();
Nop();
RCSTA1bits.CREN = 1;
}
I'm trying to debugging my code on the PIC24F04KA200. But when i start debugging, i get the message:
The target device is not ready for debugging. Please check your configuration bit settings and program the device before proceeding. The most common causes for this failure are oscillator and/or PGC/PGD settings.
I readed the PicKit3 User guide, but i don't find the answer. The PicKit is connected to the PGC2 and PGD2 pins. My configuration bits:
/*
* File: config.h
*
*/
#ifndef CONFIG_H
#define CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_H */
#include <p24F04KA200.h>
// PIC24F04KA200 Configuration Bit Settings
// 'C' source line config statements
#include <xc.h>
// FBS
// FGS
#pragma config GWRP = OFF // General Segment Code Flash Write Protection bit (General segment may be written)
#pragma config GCP = OFF // General Segment Code Flash Code Protection bit (No protection)
// FOSCSEL
#pragma config FNOSC = FRCDIV // Oscillator Select (8 MHz FRC oscillator with divide-by-N (FRCDIV))
#pragma config IESO = OFF // Internal External Switch Over bit (Internal External Switchover mode disabled (Two-Speed Start-up disabled))
// FOSC
#pragma config POSCMOD = NONE // Primary Oscillator Configuration bits (Primary oscillator disabled)
#pragma config OSCIOFNC = ON // CLKO Enable Configuration bit (CLKO output disabled)
#pragma config POSCFREQ = MS // Primary Oscillator Frequency Range Configuration bits (Primary oscillator/external clock input frequency between 100 kHz and 8 MHz)
#pragma config SOSCSEL = SOSCHP // SOSC Power Selection Configuration bits (Secondary oscillator configured for high-power operation)
#pragma config FCKSM = CSECMD // Clock Switching and Monitor Selection (Clock switching is enabled, Fail-Safe Clock Monitor is disabled)
// FWDT
#pragma config WDTPS = PS32768 // Watchdog Timer Postscale Select bits (1:32,768)
#pragma config FWPSA = PR128 // WDT Prescaler (WDT prescaler ratio of 1:128)
#pragma config WINDIS = OFF // Windowed Watchdog Timer Disable bit (Standard WDT selected; windowed WDT disabled)
#pragma config FWDTEN = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
// FPOR
#pragma config BOREN = BOR0 // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware; SBOREN bit disabled)
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BORV = LPBOR // Brown-out Reset Voltage bits (Low-Power Brown-out reset occurs around 2.0V)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RA5 input pin disabled)
// FICD
#pragma config ICS = PGx2 // Reserved (PGC2/PGD2 are used for programming the device)
// FDS
#pragma config DSWDTPS = DSWDTPSF // Deep Sleep Watchdog Timer Postscale Select bits (1:2,147,483,648 (25.7 Days))
#pragma config DSLPBOR = OFF // Deep Sleep Zero-Power BOR Enable bit (Deep Sleep BOR disabled in Deep Sleep)
#pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable bit (DSWDT disabled)
And my main file:
/*
* File: main.c
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
while(1)
{
;
}
}
The processor is running. I have a blinkerLed program running.
Does anyone have a suggestion?
That micro-controller does not have embedded debugging capabilities. If you want to debug your application for this UC, you'll have to use an emulator or the simulator (not my favorite but it can sometimes get you out of a bind).
From the Microchip website:
Featuring nanoWatt XLP Technology ideal for battery applications
(Please use PIC24F16KA102 Processor Extention Pack for Emulation and
Debug Support-AC244028. This MCU does not have on-chip debug
capability)