PIC16F887 PORT won't work with XC8 C compiler - c

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.

Related

Reading pins of a pic12f1840

I'm using a pic12f1840 width a pickit3 and mplab x ide (and x8 c compiler). It is probably really easy, but I can't figure out how to read the value of a pin!
void main(void) {
//setting up TESA
TRISA = 0b111111;
TRISA5 = 0; //pin 5 is output
TRISA1 = 1; //pin 1 in input
for (;;) {
RA5 = RA1;
}
}
This is my code at the moment (I left out the configs and include). I have a led connected to pin 5, and a button (with a pulldown resistor) connected to pin 1. I'm running the whole thing on 3.3 volts.
When dealing with Microchip controllers like the PIC it a real good idea to post a complete code that builds. From my experience the real issue is almost always in the stuff the Original Poster left out.
This code works for me in the simulator:
/*
* File: main.c
* Author: dan1138
* Compiler: XC8 v2.20
* IDE: MPLABX v5.40
*
* Created on September 29, 2020, 1:24 PM
*/
// PIC12F1840 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#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 = 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 CPD = OFF // Data Memory Code Protection (Data 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 IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#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 LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
void main(void) {
//setting up TESA
TRISA = 0b111111;
ANSELA = 0; /* make all of PORTA digital I/O */
TRISAbits.TRISA5 = 0; //pin 5 is output /* use Microchip suggested syntax */
TRISAbits.TRISA1 = 1; //pin 1 in input /* use Microchip suggested syntax */
for (;;) {
LATAbits.LATA5 = PORTAbits.RA1; /* use Microchip suggested syntax */
}
}
In your case it seems to be two things:
Not knowing you need to configure GPIO pins for digital operations.
Simple syntax errors.
My example code uses the syntax that's been typically supported by almost all versions of the XC8 compilers for about 10 years now.
The shorter forms you have used may not always available for every controller you could target.

Trying to understand Microchip PIC16LF15344 peripheral pin selection for I2C

I have been reviewing the Microchip PIC16LF15344 datasheet for peripheral pin selection, and either I am reading it incorrectly or it appears to have errors and inconsistencies in the document. I would like to know if anyone else has used this device and can confirm my interpretation.
I'm trying to write code for a PIC16LF15344 to make use of the I2C interface. I have managed to write I2C code for a PIC16LF1822 that works fine, but I have so far been unable to get this to work on the PIC16LF15344, and there is some confusing documentation in the data sheet that I would like to get cleared up.
Here is a reference to the datasheet.
The pinout descriptions for the PIC16LF15344 shows that the I2C SDA function can be allocated to RC1 or RB6. Likewise, I2C SCL may be allocated to RC0 or RB4. But there is a note in Section 15.3 Bidirectional Pins as follows.
The I2C SCLx and SDAx functions can be remapped through PPS. However, only the RB1, RB2, RC3, and RC4 pints have the I2C and SMBus specific input buffers implemented (I2C mode disables INLVL and sets thresholds that are specific for I2C). If the SCLx or SDAx functions are mapped to some other pin (other than RB1, RB2, RC3, or RC4), the general purpose TTL or ST input buffers (as configured based on INLVL register setting) will be used instead. In most applications, it is therefore recommended only to map the SCLx and SDAx pin functions to the RB1, RB2, RC3 or RC4 pins.
The problem is not only does the note appear to conflict with the descriptions in the pin allocation tables, it also references pins RB1 and RB2, which don't appear anywhere in the pin allocation tables, i.e., they don't appear to exist for this PIC. I see similar footnote references to RB1 and RB2, but they are not documented anywhere in the body of the document or the tables.
Certainly this must be a documentation error, but I can find no current errata on the PIC16LF15324/44 datasheet to correct this. Am I reading this right?
I have tried configuring SCL and SDA with PPS to pins RC0 and RC1, since that is how they are wired on my PCB, but I can't get the I2C working yet using essentially the same software that I was using for the PIC16LF1822. The PPS default for EUSART TX2 and RX2 are RC0 and RC1. Does that mean I need to use TX2CKPPS and RX2DTPPS to move the EUSART assignments elsewhere before using SSP1CLKPPS and SSP1DATPPS to assign SCL and SDA to RC0 and RC1?
I will be investigating other potential problems with my PCB, but I want to get this straightened out before I submit another PCB for fab. I need to make some changes anyway, so I might just connect SCL and SDA to their PPS defaults in the next version and try again.
Here is the initialization code:
OSCFRQbits.HFFRQ = 0b011; // Set internal HF oscillator frequency to 8 MHz
WPUA = 0b00111111; // Enable all weak pull-up resistors on port A
WPUB = 0b11110000; // Enable all weak pull-up resistors on port B
WPUC = 0b11111100; // Enable all weak pull-up resistors on port C except
// RC0 and RC1 to be used as I2C SCL and SDA
TRISA = 0b00110000; // Set RA4 and RA5 as inputs
ANSELA = 0b00110000; // Set RA4 and RA5 to analog
TRISB = 0b00110000; // Set RB6 and RB7 as inputs
ANSELB = 0b11000000; // Set RB6 and RB7 as analog
TRISC = 0b11111011; // Set RC0, RC1, RC3, RC4, RC5, RC6, and RC7 as inputs
ANSELC = 0b11111000; // Set RC3, RC4, RC5, RC6, and RC7 as analog
TX2CKPPS = 0b01100; // Use RB4 for TX2
RX2DTPPS = 0b01110; // Use RB6 for RX2
SSP1CLKPPS = 0b10000; // Use RC0 as SCL
SSP1DATPPS = 0b10001; // Use RC1 as SDA
SSP1CON1 = 0b00100110; // SSPEN enabled, WCOL no collision, SSPOV no overflow,
// CKP low hold, SSPM I2C slave 7-bit
SSP1CON2 = 0b00000000; // ACKSTAT received, RCEN disabled, RSEN disabled,
// ACKEN disabled, ACKDT acknowledge, SEN disabled,
// GCEN disabled, PEN disabled
SSP1CON3 = 0b00000000; // BOEN disabled, AHEN disabled, SBCDE disabled,
// SDAHT 100 ns hold, ACKTIM ackseq, DHEN disabled,
// PCIE disabled, SCIE disabled
SSP1STAT = 0x00;
SSP1BUF = 0x00;
SSP1MSK = 0xff;
SSP1ADD = I2C_SLAVE_ADDR << 1;
PIR3bits.SSP1IF = 0; // Clear the SSP Interrupt flag
PIE3bits.SSP1IE = 1; // Enable SSP Interrupts
INTCONbits.GIE = 1; // Enable global interrupts
INTCONbits.PEIE = 1; // Enable peripheral interrupts
You likely have several issues to deal with.
All of the default I2C pins also have analog functionality too. Be sure that the ANSB or ANSC bits that are associated with the I2C pins are setup for digital operation.
While the power on reset selects the data sheet defaults for the I2C input pin assignments the I2C outputs by default are not assigned to any GPIO pin. You will need to place the I2C outputs for SCL and SDA in the correct PPS mapping registers.
Note that regardless of the I2C master or slave implementation both the input and output functions should be mapped to the same pin.
It would help to edit your question and post the code that you use to initialize the I2C pins and PPS mapping registers.
/*
* File: main.c
* PIC16LF15354
* +-------------:_:-------------+
* 10K Pull-Up -> 1 : RE3/MCLR ANB7/RX2/PGD/RB7 : 28 <>
* <> 2 : RA0/ANA0 ANB6/TX2/PGC/RB6 : 27 <> RX2
* <> 3 : RA1/ANA1 ANB5/RB5 : 26 <>
* <> 4 : RA2/ANA2 ANB4/RB4 : 25 <> TX2
* <> 5 : RA3/ANA3 ANB3/RB3 : 24 <>
* <> 6 : RA4/ANA4 ANB2/SDA2/RB2 : 23 <>
* <> 7 : RA5/ANA5 ANB1/SCL2/RB1 : 22 <>
* GND -> 8 : VSS ANB0/RB0 : 21 <>
* <> 9 : RA7/OSC1/ANA7 VDD : 20 <- 3v3
* <> 10 : RA6/OSC2/ANA6 VSS : 19 <- GND
* SCL1 <> 11 : RC0/ANC0 ANC7/RX1/RC7 : 18 <>
* SDA1 <> 12 : RC1/ANC1 ANC6/TX1/RC6 : 17 <>
* <> 13 : RC2/ANC2 ANC5/RC5 : 16 <>
* <> 14 : RC3/SCL1/ANC3 ANC4/SDA1/RC4 : 15 <>
* +-----------------------------:
* DIP-28
*
* Created on January 4, 2019, 6:20 PM
*/
// PIC16LF15354 Configuration Bit Settings
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = SWDTEN // WDT operating mode (WDT enabled/disabled by SWDTEN bit in WDTCON0)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
#pragma config BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)
#pragma config CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)
#include <xc.h>
#define I2C_SLAVE_ADDR 0x00
void main(void)
{
WPUA = 0b00111111; // Enable all weak pull-up resistors on port A
WPUB = 0b11110000; // Enable all weak pull-up resistors on port B
WPUC = 0b11111100; // Enable all weak pull-up resistors on port C except
// RC0 and RC1 to be used as I2C SCL and SDA
TRISA = 0b00110000; // Set RA4 and RA5 as inputs
ANSELA = 0b00110000; // Set RA4 and RA5 to analog
TRISB = 0b00110000; // Set RB6 and RB7 as inputs
ANSELB = 0b11000000; // Set RB6 and RB7 as analog
TRISC = 0b11111011; // Set RC0, RC1, RC3, RC4, RC5, RC6, and RC7 as inputs
ANSELC = 0b11111000; // Set RC3, RC4, RC5, RC6, and RC7 as analog
#ifdef WRONG_WAY_TO_DO_PPS
TX2CKPPS = 0b01100; // Use RB4 for TX2
RX2DTPPS = 0b01110; // Use RB6 for RX2
SSP1CLKPPS = 0b10000; // Use RC0 as SCL
SSP1DATPPS = 0b10001; // Use RC1 as SDA
#else
RB4PPS = 0x11; // Assign TX2 output to RB4
RX2DTPPS = 0x0E; // Assign RB6 to RX2 input
RC0PPS = 0x15; // Assign SCL1 output to RC0
SSP1CLKPPS = 0x10; // Assign RC0 to SCL1 input
RC1PPS = 0x16; // Assign SDA1 output to RC1
SSP1DATPPS = 0x11; // Assign RC1 to SDA1 input
#endif
SSP1CON1 = 0b00100110; // SSPEN enabled, WCOL no collision, SSPOV no overflow,
// CKP low hold, SSPM I2C slave 7-bit
SSP1CON2 = 0b00000000; // ACKSTAT received, RCEN disabled, RSEN disabled,
// ACKEN disabled, ACKDT acknowledge, SEN disabled,
// GCEN disabled, PEN disabled
SSP1CON3 = 0b00000000; // BOEN disabled, AHEN disabled, SBCDE disabled,
// SDAHT 100 ns hold, ACKTIM ackseq, DHEN disabled,
// PCIE disabled, SCIE disabled
SSP1STAT = 0x00;
SSP1BUF = 0x00;
SSP1MSK = 0xff;
SSP1ADD = I2C_SLAVE_ADDR << 1;
PIR3bits.SSP1IF = 0; // Clear the SSP Interrupt flag
PIE3bits.SSP1IE = 1; // Enable SSP Interrupts
INTCONbits.GIE = 1; // Enable global interrupts
INTCONbits.PEIE = 1; // Enable peripheral interrupts
/*
* Embedded code never returns from main
*/
for(;;)
{
}
}
The PPS is setup correctly but I do not know if the I2C initialization code is right.

Microchip Starter Kits with SPI mode

I want to use microcontrollers for communicating data by SPI. So, I have chosen firstly the Microchip USB Starter Kit III module which has a PIC32MX470F512L. I tried several ways to code its SPI, but only the clock signal SCK can be seen on an oscilloscope.
Then, i tried the same code (just adjusted a few code lines to the new PIC) with the Microchip Starter Kit I which has a PIC32MX360F512L. And all run perfectly. So, i don't understand why the USB Starter Kit III doesn't work for SPI communication?
I give you the code used to test the SPI SDO & /SS.
#define _SUPPRESS_PLIB_WARNING
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
#include <p32xxxx.h>
#include <xc.h>
#include <peripheral/spi.h>
// DEVCFG2
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier (24x Multiplier)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 256)
// DEVCFG1
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = HS // Primary Oscillator Configuration (HS osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/8)
#pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is Enabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)
int main(void) {
TRISGbits.TRISG6=0; //SCK2
TRISGbits.TRISG7=1; //SDI2
TRISGbits.TRISG8=0; //SDO2
TRISGbits.TRISG9=0; //SS2
OpenSPI2(SPI_MODE16_ON|SPI_SMP_ON|MASTER_ENABLE_ON|SEC_PRESCAL_5_1|PRI_PRESCAL_16_1, SPI_ENABLE);
int data;
PORTGbits.RG9 = 1;
while(1)
{
PORTGbits.RG9 = 0;
putcSPI2(0xaaaa);
data=getcSPI2();
PORTGbits.RG9 = 1;
}
return 0;
}
Thanks
Pin Mapping
Do you do the pin mapping ? It does not appear on the code your posted.
You need to assign the pin to the SPI Module using the PPS (peripheral pin select).
OpenSPI is a library function, but it's also needed to do the pin mapping with the pin peripheral select (PPS)
Point 12.3.1 http://ww1.microchip.com/downloads/en/DeviceDoc/60001120F.pdf
Pin State (analog / digital)
Check your pin are not in (default) analog state. If the pin also has an analog (AN) function, the default state will be analog and you cannot control that pin. You need to set the register ANSELx (or AD1PCFG) to set the pin.
In the chip PIC32MX470F512L the pin you are using (RG6-9) also has analog function (AN):
10 AN16/C1IND/RPG6/SCK2/PMA5/RG6
11 AN17/C1INC/RPG7/PMA4/RG7
12 AN18/C2IND/RPG8/PMA3/RG8
14 AN19/C2INC/RPG9/PMA2/RG9
Page 7 http://ww1.microchip.com/downloads/en/DeviceDoc/60001185F.pdf
Analog pin Section 12.2.5 http://ww1.microchip.com/downloads/en/DeviceDoc/60001120F.pdf
Hi everyone and thanks for your replies !
Thanks to your help, i found out that issue. Pin configuration was necesary. Below the code i added for pin configuration.
// Mapping SPI1 & SPI2
SDI1Rbits.SDI1R = 0xa; // SDI1 to C4
RPD0Rbits.RPD0R = 0x8; // SDO1 to D0
RPB2Rbits.RPB2R = 0x7; // SS1 to B2
SDI2Rbits.SDI2R = 0x1; // SDI2 to G7
RPG8Rbits.RPG8R = 0x6; // SDO2 to G8
RPG9Rbits.RPG9R = 0x6; // SS2 to G9

Why this simple PWM doesn't work in xc8

I know there are a lot of examples in internet, but what does need this code to work ?
frecuency oscillator = 4mhz
periode = 0.25us
duty_cicle = 250
Prescale = 16
PR2 = 124
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic16f88.h>
#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 ()
{
while (1)
{
CCP1CON = 0x2C; /*activate PWM mode*/
PR2 = 0x7C; /*124 (DECIMAL)*/
T2CON = 0X06; /*prescale 16 */
CCPR1L = 0X3E;
}
}
I want to see :
Period of PWM = 2ms
Dutycicle = 1ms
Sincerilly
NIN
First off topic:
Don't include pic16f88.h, it's included by xc.h.
Little more off topic:
If you use a more modern part (e.g. PIC16f1619), you can use the MPLAB Code Configurator to generate the TMR2 and CCP code for you. It'll also cost less and have more flash/ram. That device is on the curiosity board ($20).
On Topic:
Your first stop is the datasheet.
The PWM section has the setup for PWM operation.
Step1:
The timer 2 takes Fosc/4 as an input, which is 1mhz in your case.
Target frequency is 500Hz. 1e6/500 = 2k.
I'd suggest a prescaler of 16, and pr value of 125. This will give you exactly 500Hz.
Step2:
We want a 50% duty cycle. CCP1L floor(125/2) = 62. CCP1X:CCP1Y = 0.5 * 4 = 2.
Step 3:
Clear the tris bit.
Step4 and 5:
Turn it on
// Step 1
TMR2ON = 0;
TOUTPS = 0;
T2CKPS = 2;
PR2 = 250U;
// Step 2
CCP1L = 62U;
CCP1X = 1;
CCP1Y = 0;
// Step 3
TRISB3 = 0;
// Step 4
TMR2ON = 1;
// Step 5
CCP1M = 0xC;
Hope that helps.
The datasheet states:
In Pulse-Width Modulation (PWM) mode, the CCP1 pin
produces up to a 10-bit resolution PWM output. Since
the CCP1 pin is multiplexed with the PORTB data latch,
the TRISB bit must be cleared to make the CCP1
pin an output.
So you must set the TRIS bit for the CCP1 pin to output:
TRISB &= ~(1 << 3); //Clear bit RB3/CCP1 in TRISB, makes PORTB3/CCP1 output.
This assumes CCPMX: CCP1 Pin Selection bit in the configuration word is clear. If set, then CCP1 is on RB0 in stead of RB3 but since I see no mention of CCPMX in your configuration pragma's i assume it is cleared.

Why won't this PIC code light up my LEDs?

The following code won't set any of the pins high on my PIC18F14K50, yet it couldn't be simpler!
#include <pic18.h>
#include <htc.h>
void main(void)
{
// Set ALL pins to output:
TRISA = 0;
TRISB = 0;
TRISC = 0;
// Set ALL pins to high:
LATA = 0b11111111;
LATB = 0b11111111;
LATC = 0b11111111;
// Leave pins high and wait forever:
while (1);
}
I'm using MPLAB v8.43 and the Hi-Tech ANSI C Compiler.
A logic probe shows none of the pins high except the VUSB and the MCLR.
Any ideas?
At least some of the pins may be configured as Analog Inputs.
From the Datasheet for this device
The operation of pin RA4 as analog is selected by setting the ANS3
bit in the ANSEL register which is the default set-ting after a
Power-on Reset.
If you do not set the ANSEL register the pin cannot be used as output as it is configured as an analog input.
This applies to all the pins that can be A/D inputs, which does not cover all the pins you have.
Then again I do not see any configuration bit setup in your code. That device e.g. has 2 different instruction sets and you have to at the very least specify which instruction set you are using in the configuration bits.
You may try adding this to the top of your code just after the includes :
// Configuration BITS setup
__CONFIG(1, FOSC_INTIO2 & XINST_OFF);
__CONFIG(2, WDTEN_OFF & PWRTEN_ON);
__CONFIG(3, MCLRE_OFF);
I suppose that you didn't configure the MCPU oscillator, try to define:
; Oscillator:
config FOSC = INTIO2 ;Internal RC oscillator
;
; PLL x4 Enable bit:
config PLLCFG = OFF
and
;Define oscillator frequency
;{
movlw b'01100000'
movwf OSCCON
movlw b'01000000'
movwf OSCTUNE
;};
This directives are for MPLAB asm and not for Hi-Tech, but file registers should have the same names.

Resources