Professional Documents
Culture Documents
This presentation contains selected illustrations and program listings from the book Programming 8-bit PIC Microcontrollers in C by Martin Bates
Part 1 Microcontroller Systems describes in detail the internal architecture and interfaces available in a typical PIC chip, and outlines the main features of the MPLAB development system Part 2 C Programming Essentials provides simple examples which introduce the basic principles of C programming for microcontrollers using CCS C
Part 3 C Peripheral Interfaces provides example programs for operating PIC chips with a full range of peripherals, using timers and interrupts
Part 3
C PERIPHERAL INTERFACES
Figure 3.1
Listing 3.1
/*
ANALIN.C MPB 5-1-07 Read & display analogue input ***************************************************************************/ #include "16F877A.h" #device ADC=8 #use delay(clock=4000000) #use rs232(baud=9600, xmit=PIN_D0, rcv=PIN_D1)
// 8-bit conversion
// LCD output
void main() //************************************************************ { int vin0; // Input variable setup_adc(ADC_CLOCK_INTERNAL); setup_adc_ports(ALL_ANALOG); set_adc_channel(0); for(;;) { // ADC clock // Input combination // Select RA0
Table 3.1
ANALOGUE INPUTS ADC SETUP ADC PINS SETUP ADC CHANNEL SELECT ADC READ
setup_adc(ADC_CLOCK_INTERNAL); setup_adc_ports(RA0_ANALOG);
set_adc_channel(0);
inval = read_adc();
Table 3.2
Operation Clears peripheral interrupt Disables peripheral interrupt Enables peripheral interrupt Checks if interrupt flag set Selects interrupt trigger edge Jump to address of ISR
INTERRUPT ENABLE
INTERRUPT ACTIVE INTERRUPT EDGE INTERRUPT JUMP
REGISTER CODE
INTERRUPT SOURCE External interrupt has been detected Change on Port B has been detected Timer 0 has overflowed (same as TIMER0 Timer 0 has overflowed (same as RTCC)
INT_TIMER1 INT_CCP1
INT_TIMER2 INT_CCP2 INT_AD INT_SSP INT_PSP INT_EEPROM
0x8C10 0x8C04
0x8C02 0x8D01 0x8C40 0x8C08 0x8C80 0x8D10
Figure 3.3
Listing 3.3
// INTEXT.C MPB 10-4-07 // Demo external interrupt RB0 low interrupts foreground output count #include "16F877A.h" #use delay(clock=4000000) #int_ext void isrext() { output_D(255); delay_ms(1000); } // Interrupt name // Interrupt service routine name // ISR action
void main() //************************************************************** { int x; enable_interrupts(int_ext); enable_interrupts(global); ext_int_edge(H_TO_L); while(1) { output_D(x); x++; delay_ms(100); } } // Enable named interrupt // Enable all interrupts // Interrupt signal polarity // Foreground loop
Table 3.5
TIMERS TIMERX SETUP TIMERX READ Set up the timer mode
Timer functions
Read a timer register (8 or 16 bits) Preload a timer register (8 or 16 bits) Select PWM, capture or compare mode Set PWM duty cycle
TIMERX WRITE
TIMER CCP SETUP TIMER PWM DUTY
Figure 3.4
CCPR1H
CCPR1L
Comparator
TMR1H
TMR1L
Instruction Clock
Listing 3.4
// PWM.C MPB 11-4-07 // Demo PWM output #include "16F877A.h" void main() { setup_ccp1(ccp_pwm); // Select timer module and mode set_pwm1_duty(500); // Set on time setup_timer_2(T2_DIV_BY_16,248,1); // Clock rate & // output period while(1){} }
Figure 3.5
Capture Hardware
CCPR1H
CCPR1L
Capture Enable
TMR1H TMR1L Instruction Clock
Listing 3.5
// PERIOD.C MPB 11-4-07 // Demo of period measurement
#include "16F877A.h" //******************************************************** #int_ccp1 void isr_ccp1() { set_timer1(0); clear_interrupt(INT_CCP1); } // Interrupt name // Interrupt function // Clear Timer1 // Clear interrupt flag
void main()//****************************************************** { setup_timer_1(T1_INTERNAL); // Internal clock setup_ccp1(CCP_CAPTURE_RE); // Capture rising edge on RC2 enable_interrupts(GLOBAL); enable_interrupts(INT_CCP1); while(1){} } // Enable all interrupts // Enable CCP1 interrupt
Figure 3.6
Table 3.6
RS232 SERIAL PORT Title RS232 SET BAUD RATE RS232 SEND BYTE RS232 SEND SELECTED RS232 PRINT SERIAL RS232 PRINT SELECTED RS232 PRINT STRING RS232 RECEIVE BYTE RS232 RECEIVE STRING RS232 RECEIVE SELECTED RS232 CHECK SERIAL RS232 PRINT ERROR
setup_uart(19200);
putc(65) s = fputc(A,01);
printf(Answer:%4.3d,n); fprintf(01,Message); sprintf(astr,Ans=%d,n);
n = getc(); gets(spoint);
astring= fgets(spoint,01);
s = kbhit();
assert(a<3);
Figure 3.1.1
Listing 3.6
Hardware UART
// HARDRS232.C MPB 13-6-07 // Serial I/O using hardware RS232 port #include "16F877A.h" #use delay(clock=8000000) RS232 #use rs232(UART1)
void main() //*************************************************** { int incode; setup_uart(9600); // Set baud rate while(1) { incode = getc(); printf(" ASCII = %d ",incode); putc(13); } }
Table 3.7
SPI SERIAL PORT Operation SPI SETUP SPI READ SPI WRITE SPI TRANSFER SPI RECEIVED Description Initialise SPI serial port
Receives data byte from SPI port Sends data byte via SPI port Send and receive via SPI Check if SPI data received
Figure 3.8
Listing 3.7
// SPIMASTER.C MPB 20-6-07 // Serial I/O using SPI synchronous link // Simulation hardware SPIC.DSN, master program, attach to U1 #include "16F877A.h" void main() { int number; //**********************************************
setup_spi(spi_master);
Figure 3.9
Table 3.8
I2C SERIAL PORT I2C START I2C WRITE I2C READ I2C STOP I2C POLL Issue start command in master mode Send a single byte Read a received byte
I2C functions
Figure 3.10
Table 3.9
PARALLEL SLAVE PORT Operation PSP SETUP PSP DIRECTION Description Enable or disable PSP Set the PSP data direction
PSP functions
pspi = psp_input_full();
pspv = psp_overflow();
Listing 3.10
// PSPMASTER.C // Test system master controller program, design file PSP.DSN, U1 #include "16F877A.h" void main() //************************************************ { int sendbyte; port_b_pullups(1); // Activate Port B pullups while(1) { sendbyte = input_B(); output_D(sendbyte); output_low(PIN_E2); output_low(PIN_E1); output_high(PIN_E1); } }
// Get test byte // Output on PSP bus // Select PSP slave // Write byte to slave port // Reset write enable