728x90

Showing posts with label Change Notify Interrupt (CNI). Show all posts
Showing posts with label Change Notify Interrupt (CNI). Show all posts

Friday, October 3, 2025

dsPIC30F2010 CCS PICC Bootloaders Example

Overview

A boot-loader is a computer program that is responsible for booting a computer and booting an operating system. If it also provides an interactive menu with multiple boot choices then it's often called a boot manager.

dsPIC30F2010 CCS PICC Bootloaders Example
dsPIC30F2010 ds18B20 Demo Program with Boot Loader

It also applicable for some 8-bit micro-controller with self re-programmable under software control capabilities, for instance the PIC16F877A, PIC16F887, PIC18F4550, dsPIC30F1010, dsPIC30F2010 etc. It's a block of micro-controller program that manage the process of loading embedded program to any location of Flash memory. It must locates at beginning or at the end of micro-controller Flash memory address.

The dsPIC30F2010 is a self re-programmable Flash micro-controller that allow the user to take the advantage of using a boot loader program.

dsPIC30F2010 CCS PICC Bootloaders Example
Program Space Memory Map for dsPIC30F2010

The user just need to burn its boot-loader firmware once using a conventional device programmer, for instance a serial port JDM programmer or even a USB PICKIT3. Then the following embedded program must reserves the boot-loader memory section to prevent ROM program overwriting.  

dsPIC30F2010 CCS PICC Bootloaders Example
Preliminary Boot Loader Firmware Flashing to dsPIC30F2010

The boot loader section should locate at the beginning or at the last section of Flash program memory space. However locating it at beginning is very suitable to prevent boot loader program overwriting that can destroy the boot loader functionalities. 

A boot-load embedded program can be uploaded to its target MCU an appropriate host PC boot-loader software on any OS platform via a typical serial port or even a USB port. CCS PICC provides a serial port and USB port boot-loader for some of their devices.

CCS PICC PCD Boot Loader Example

Boot Loader for 8-bit PIC Micro-controllers  

CCS PICC provide C boot/boot-loader C driver and example for its target chips. For its 8-bit PIC16 and PIC18 chips there are a "bootloader.h" header file and "loader.c" C driver. We can check its "ex_bootloader.c" for boot-loader firmware and "ex_bootload.c" for boot program example. In that example, the boot-loader firmware locates at the beginning of program memory. This example boot the program via RS-232 port.

On the other hand we can use CCS PICC Create Project Wizard to generate a boot-loader firmware for 8-bit PIC micro-controllers. There are two options, boot-loader at the start of memory and boot-loader at the end of memory. 

There many method of bootloading the program such as I2C and USB. 

Boot Loader for 16-bit PIC Micro-controllers  

Since the architecture of 16-bit DSC PIC micro-controllers are far different from the 8-bit PIC micro-controllers, the boot-loader C driver are in separated files. There are two C driver files, the "pcd_bootloader.h" and the "loader_pcd.c" C source files. 

There are two C examples file of using the PCD boot-loader firmware. The "ex_pcd_bootloader.c" is firmware of boot-loader prior to boot program. It requires a user input button and reset button to enter firmware loading mode. The "ex_pcd_bootload.c" C sample program is an example of loading the boot program into the chip. It use CCS PICC Serial Input/Output software and boot-loader software to load the program. In this program the boot-loader section locates at the beginning of the program.

Some newer version of CCS PICC as an instance of CCS PICC v5.119 has problem when compiling the boot-loader firmware for some dsPIC30FXXXX series. However I use an older version of CCS PICC v5.049 instead. It works very well without errors and problems.

dsPIC30F2010 CCS PICC Bootloaders Example
CCS PICC v5.049 IDE

Boot Loader firmware

Initially I need to prepare a boot-loader firmware for my dsPIC30F2010 DSC.

pcd_bootloader.c


  1. /*CCS PICC Compiler version 5.049*/
  2. #include <30F2010.h>
  3. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  4. #use delay(clock=20000000)
  5. #use rs232(BAUD=9600,UART1)

  6. #define PUSH_BUTTON PIN_C14
  7. #define BOOT_LED PIN_D0

  8. #define _bootloader
  9. //#define BOOTLOADER_MODE2X

  10. #include <pcd_bootloader.h>
  11. #include <loader_pcd.c>

  12. #org APPLICATION_START
  13. void application(void)
  14. {
  15. while(TRUE);
  16. }

  17. void main(void)
  18. {
  19. output_c(0);
  20. output_d(0);
  21. set_tris_d(0);
  22. set_tris_c(1<<14);
  23. //set_pullup(TRUE,PUSH_BUTTON);
  24. output_high(PUSH_BUTTON);
  25. if(!input(PUSH_BUTTON))
  26. {
  27. output_high(BOOT_LED);
  28. // Let the user know it is ready to accept a download
  29. printf("\r\nWaiting for download...");
  30. // Load the program
  31. load_program();
  32. }
  33. output_low(BOOT_LED);
  34. application();
  35. while(1);
  36. }

  37. #int_default
  38. void isr(void)
  39. {
  40. jump_to_isr(LOADER_END+5);
  41. }


After compile this program I need to burn its hex file into my target chip using a PICKIT2 device programmer.

dsPIC30F2010 CCS PICC Bootloaders Example
Preliminary Boot Loader Firmware Flashing to dsPIC30F2010

From this point the dsPIC30F2010 has a start-of-memory boot-loader firmware. It doesn't need a device programmer any more. That is a blank program that contain only boot-loader section. To test how it works we just, 

1- press and hold the input push button connects to pin RC14

2- at the same time press the reset button and release them.

3- then you will see an LED(pin RD0) turns on the micro-controller enter its loading program mode. 

dsPIC30F2010 CCS PICC Bootloaders Example
The dsPIC30F2010 Prototype Board waiting for program loading

 

dsPIC30F2010 CCS PICC Bootloaders Example
dsPIC30F2010 waiting for loading program from host PC
 

Click here to download this example package.

Boot Load Example Program

From here we can load any firmware with a boot loader setting to dsPIC30F2010 via host PC serial port and CCS PICC boot loader software. I modify the "ex_pcd_bootload.c" to blinks an LED then I load it into the dsPIC30F2010 via CCS PICC boot-loader software.



  1. /*CCS PICC Compiler version 5.049*/
  2. #include <30F2010.h>
  3. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  4. #use delay(clock=20M)
  5. #use rs232(UART1,BAUD=9600)

  6. //#define BOOTLOADER_MODE2X

  7. //This is a necessary include file. It reserves space so that the
  8. //bootloader is not overwritten.
  9. #include <pcd_bootloader.h>

  10. #define LED_0 PIN_D1

  11. print_message(void){
  12. delay_ms(10);
  13. printf("\rCCS PICC v5.049 PCD BOOTLOADER\n\r");
  14. }

  15. void main()
  16. {
  17. print_message();
  18. unsigned int16 counter=0;
  19. output_d(0);
  20. set_tris_d(0);
  21. while(TRUE)
  22. {
  23. output_toggle(LED_0);
  24. printf("Counter Variable: %Lu\n\r",counter);
  25. counter++;
  26. delay_ms(1000);
  27. }
  28. }


After compile this program we just press and hold the boot button, and then press and release the reset pin to enter programming loading mode.

Make sure that the SIOW.exe is already open and connected with an appropriate baud rate. 


dsPIC30F2010 CCS PICC Bootloaders Example
press and hold the boot button, and then press and release the reset pin

 

dsPIC30F2010 CCS PICC Bootloaders Example
CCS PICC SIOW Waiting for download

 

dsPIC30F2010 CCS PICC Bootloaders Example
Click on CCS PICC Bootloader tool

 

dsPIC30F2010 CCS PICC Bootloaders Example
Downloading Program

After the program downloading is completed the application on the MCU will run.

dsPIC30F2010 CCS PICC Bootloaders Example
Running Program

 Click here to download this example.

ds18B20 LCD Example with Boot-Loader

I modify my program in this post adding a boot-loader program. However it consumes more program memory. I copied the "ds18b20.c" to my project folder since the older version of v5.049 doesn't have this driver.

  • pcd_bootload_ds18b20_lcd.c
  

  1. /*CCS PICC Compiler version 5.049*/
  2. #include <30F2010.h>
  3. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  4. #use delay(clock=20M)
  5. #use rs232(UART1,BAUD=9600)

  6. //#define BOOTLOADER_MODE2X

  7. //This is a necessary include file. It reserves space so that the
  8. //bootloader is not overwritten.
  9. #include <pcd_bootloader.h>

  10. #define PIN_DS18B20_DATA PIN_B0
  11. #include "ds18b20.c"

  12. #define LCD_RS_PIN PIN_E4
  13. #define LCD_RW_PIN PIN_E5
  14. #define LCD_ENABLE_PIN PIN_E5
  15. #define LCD_DATA4 PIN_E0
  16. #define LCD_DATA5 PIN_E1
  17. #define LCD_DATA6 PIN_E2
  18. #define LCD_DATA7 PIN_E3

  19. #include "lcd.c"

  20. #define lcd_clear() lcd_putc('\f')
  21. #define lcd_home() lcd_putc('\a')
  22. /*For 16x4 LCD Only*/
  23. #define line_1() lcd_send_byte(0,0x80);
  24. #define line_2() lcd_send_byte(0,0xC0);
  25. #define line_3() lcd_send_byte(0,0x90);
  26. #define line_4() lcd_send_byte(0,0xD0);

  27. print_message(void){
  28. delay_ms(10);
  29. printf("\rCCS PICC v5.049 PCD BOOTLOADER\n\r");
  30. }

  31. void main(){
  32. print_message();
  33. signed int16 val;
  34. printf("\n\rdsPIC30F2010 Prototype Board.");
  35. printf("\n\rSaturday 26th September 2025");
  36. printf("\n\rds18b20 Humidity Sensor Example\n\r");
  37. printf("\r\n\r\ds18b20.c - DHT11 example starting\r\n\r\n");
  38. ds18b20_init();
  39. lcd_init();
  40. printf(LCD_PUTC,"dsPIC30F2010 LCD");
  41. line_2();
  42. printf(LCD_PUTC,"ds18b20 Sensor");
  43. line_3();
  44. printf(LCD_PUTC,"PCD BootLoader");
  45. line_4();
  46. printf(LCD_PUTC,"CCS PICC v5.049");
  47. delay_ms(5000);
  48. lcd_clear();
  49. while(1){
  50. ds18b20_read(&val);
  51. printf("temperature = %ldC\r\n", val/(signed int16)16);
  52. lcd_home();
  53. printf(LCD_PUTC," ds18b20 Sensor");
  54. line_2();
  55. printf(LCD_PUTC," Temperature");
  56. line_3();
  57. printf(LCD_PUTC," %ld%cC",val/(signed int16)16,0xDF);
  58. line_4();
  59. printf(LCD_PUTC," and %f%cF",1.8*(val/(signed int16)16)+32,0xDF);
  60. delay_ms(1000);
  61. }
  62. }

Since the boot-loader section locates at the start of program memory. It doesn't matter even the the compiled boot-load application exceeds the the ROM capacity. It just has an abnormal function.

dsPIC30F2010 CCS PICC Bootloaders Example
CCS PICC Memory Use


 I tested it on my DIY dsPIC30F2010 Prototype Board.

dsPIC30F2010 CCS PICC Bootloaders Example
Downloading the program

 

After uploading this program we can see the result.

dsPIC30F2010 CCS PICC Bootloaders Example
Data send over serial port

 This C driver work fine as I prototype it on my PCBA.

dsPIC30F2010 CCS PICC Bootloaders Example
dsPIC30F2010 ds18B20 Demo Program with Boot Loader

 
dsPIC30F2010 CCS PICC Bootloaders Example
ds18B20 Temperature Sensor Reading

Click here to download this example.


 

DHT-11 LCD Example with Boot-Loader

I add this boot-load feature to my previous programming example that the dsPIC30F2010 read the humidity and temperature data from a DHT-11 environmental sensor. The result will display on a TC1604A-04 16x4 LCM. 



  1. /*CCS PICC Compiler version 5.049*/
  2. #include <30F2010.h>
  3. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  4. #use delay(clock=20M)
  5. #use rs232(UART1,BAUD=9600)

  6. //#define BOOTLOADER_MODE2X

  7. //This is a necessary include file. It reserves space so that the
  8. //bootloader is not overwritten.
  9. #include <pcd_bootloader.h>

  10. #define LED_0 PIN_D1

  11. #define PIN_DHT11_DATA PIN_B0
  12. #include "dht11.c"
  13. #define LCD_RS_PIN PIN_E4
  14. #define LCD_RW_PIN PIN_E5
  15. #define LCD_ENABLE_PIN PIN_E5
  16. #define LCD_DATA4 PIN_E0
  17. #define LCD_DATA5 PIN_E1
  18. #define LCD_DATA6 PIN_E2
  19. #define LCD_DATA7 PIN_E3

  20. #include "lcd.c"

  21. #define lcd_clear() lcd_putc('\f')
  22. #define lcd_home() lcd_putc('\a')
  23. /*For 16x4 LCD Only*/
  24. #define line_1() lcd_send_byte(0,0x80);
  25. #define line_2() lcd_send_byte(0,0xC0);
  26. #define line_3() lcd_send_byte(0,0x90);
  27. #define line_4() lcd_send_byte(0,0xD0);

  28. print_message(void){
  29. delay_ms(10);
  30. printf("\rCCS PICC v5.049 PCD BOOTLOADER\n\r");
  31. }

  32. void main()
  33. {
  34. print_message();
  35. unsigned int8 relativeHumidity;
  36. unsigned int8 tempC;
  37. printf("\n\rdsPIC30F2010 Prototype Board.");
  38. printf("\n\rFriday 26 September 2025");
  39. printf("\n\rDHT-11 Humidity Sensor Example\n\r");
  40. printf("\r\n\r\dht-11.c - DHT11 example starting\r\n\r\n");
  41. dht11_init();
  42. lcd_init();
  43. printf(LCD_PUTC,"dsPIC30F2010 LCD");
  44. line_2();
  45. printf(LCD_PUTC,"DHT-11 Sensor");
  46. line_3();
  47. printf(LCD_PUTC,"PCD BootLoader");
  48. line_4();
  49. printf(LCD_PUTC,"CCS PICC v5.049");
  50. delay_ms(5000);
  51. lcd_clear();
  52. while(1){
  53. dht11_read(&relativeHumidity, &tempC);
  54. printf("HUMIDITY=%03u%%, TEMPERATURE=%02uC\r\n", relativeHumidity, tempC);
  55. lcd_home();
  56. printf(LCD_PUTC," DHT-11 Sensor");
  57. line_2();
  58. printf(LCD_PUTC," Reading:");
  59. line_3();
  60. printf(LCD_PUTC,"Humidity: %03u%%",relativeHumidity);
  61. line_4();
  62. printf(LCD_PUTC,"Temperature:%02u%cC",tempC,0xDF);
  63. output_toggle(LED_0);
  64. delay_ms(1000);
  65. }
  66. }

 The total line of program instructions is less then the previous example (275 instructions).

M:\ccs picc\v5.049\dsPIC30F2010\pcd_bootload_dht11 - 1604LCD\Media
Program Uploading

 The sensor data also send over the PC serial port.

 

dsPIC30F2010 CCS PICC Bootloaders Example
CCS PICC SIOW Data Sending

dsPIC30F2010 CCS PICC Bootloaders Example
Start-Up Program


dsPIC30F2010 CCS PICC Bootloaders Example
Environmental Data Reading/Displaying

 


Click here to download this example.


Tuesday, September 16, 2025

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)

In previous post I putted some examples of using the dsPIC30F2010 prototype board. However it's too long. So I need to write some remaining posts here.

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
PCBWay.com Sponsor PCB Project

 

Creating a PWM Output Using Code Generation Wizard

Generating a PWM output signal could be done from scratch with a few line of code using CCS PICC. We can use its code generation wizard or even manually. 

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
PWM Output Pin of OC1
 

After clicking on Create Project it will generate source code. Then pressing F9 to compile this project.

The main.c C source code is just like below.

  1. #include <main.h>


  2. void main()
  3. {

  4. while(TRUE)
  5. {
  6. //TODO: User Code
  7. }

  8. }

 Then double click on the main.h header file we will see its source code.

  1. #include <30F2010.h>
  2. #device ICSP=1
  3. #use delay(crystal=20000000)

  4. #FUSES NOWDT //No Watch Dog Timer
  5. #FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled


  6. #use pwm(OC1,TIMER=2,FREQUENCY=10000,DUTY=0)


It will generate a PWM signal output at pin OC1 (RC13) with a frequency of 10kHz and 0% duty cycle. If we want a 50% duty cycle we need to change the DUTY parameter to 50, and rebuilt it.

PWM Duty Cycle Adjusting with ADC

After using the code generation wizard I got some idea of using PWM in CCS PICC. So I modify and write more codes to adjust PWM signal. I use the on-board ADC input from a potentiometer. Then it will convert to PWM duty cycle ranging from 0% to 100%.

  1. #include "board.h"

  2. #use pwm(OC1,TIMER=2,FREQUENCY=10000,STREAM=_1,DUTY=50)
  3. void main()
  4. {
  5. long adc_value = 0;
  6. float duty_cycle = 0;
  7. setup_adc_ports(sAN4);
  8. setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);


  9. while(TRUE)
  10. {
  11. //TODO: User Code
  12. set_adc_channel(4);
  13. delay_us(10);
  14. adc_value = read_adc();
  15. duty_cycle = (1000.0*adc_value)/1023;
  16. pwm_set_duty(_1,(int)duty_cycle);
  17. //pwm_set_duty_percent(_1,(int)duty_cycle);
  18. delay_ms(100);
  19. }

  20. }


And its "board.h" file:

  1. #include <30F2010.h>
  2. #device ADC=10
  3. #device ICSP=1
  4. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  5. #use delay(crystal=20000000)


  6. #use FIXED_IO( D_outputs=PIN_D1,PIN_D0 )
  7. #use rs232(UART1, baud=9600, stream=UART_PORT1)

  8. #define LED0 PIN_D0
  9. #define LED1 PIN_D1
  10. #define SW0 PIN_C13
  11. #define SW1 PIN_C14

  12. #define DELAY 500


It work fine without wiring additional components. However we can connect the OC1(RC13) PWM pin to a larger LED ( for instance a 5VDC 10mm LED).

 

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
Low Duty Cycle

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
High Duty Cycle

Click here to download its source file.  

ADC with On-board Tactile Switches and PWM

Fortunately there are two on-board tactile switches that could be used to adjust PWM duty cycle. So I will use ADC channel 4, SW4 (RC13) and SW5(RC14) to adjust PWM duty cycle of OC1 and OC2 respectively.

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
PWM Adjustment Using Pot and Tactile Switches

The PWM OC1 is generated by Timer 2 while the PWM OC2 is generated by Timer 3. 

  1. #include "board.h"

  2. #use pwm(OC1,TIMER=2,FREQUENCY=10000,STREAM=_1,DUTY=0)
  3. #use pwm(OC2,TIMER=3,FREQUENCY=10000,STREAM=_2,DUTY=0)

  4. void main()
  5. {
  6. long adc_value = 0;
  7. int oc2_count=0;
  8. float duty_cycle = 0;
  9. set_pullup(TRUE,PIN_C13);
  10. set_pullup(TRUE,PIN_C14);
  11. setup_adc_ports(sAN4);
  12. setup_adc(ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31);

  13. while(TRUE)
  14. {
  15. //TODO: User Code
  16. set_adc_channel(4);
  17. delay_us(10);
  18. adc_value = read_adc();
  19. duty_cycle = (1000.0*adc_value)/1023;
  20. pwm_set_duty(_1,(int)duty_cycle);
  21. if(input(SW0)==0){
  22. if(oc2_count<1000) oc2_count+=100;
  23. pwm_set_duty(_2,oc2_count);
  24. delay_ms(250);
  25. }
  26. if(input(SW1)==0){
  27. if(oc2_count>0) oc2_count-=100;
  28. pwm_set_duty(_2,oc2_count);
  29. delay_ms(250);
  30. }
  31. }

  32. }


Its "board.h" header file:

  1. #include <30F2010.h>
  2. #device ADC=10
  3. #device ICSP=1
  4. #fuses HS,NODEBUG,NOWDT,PR,CKSFSM
  5. #use delay(crystal=20000000)

  6. #use rs232(UART1, baud=9600, stream=UART_PORT1)

  7. #define LED0 PIN_D0
  8. #define LED1 PIN_D1
  9. #define SW0 PIN_C13
  10. #define SW1 PIN_C14

  11. #define DELAY 500

Click here to download its source file.

Timer Tick Example

We can use timer tick for timing delay and scheduling instead of using the delay function. We can call it from scratch using the CCS PICC IDE PIC24 project wizard.

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
Timer Tick Example Using Timer 1

 Then we get generated code lists below.

  • main.h
  1. #include <30F2010.h>
  2. #device ICSP=1
  3. #use delay(crystal=20000000)

  4. #FUSES NOWDT //No Watch Dog Timer
  5. #FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled


  6. #use timer(timer=1,tick=100us,bits=32,NOISR)

  7. #define TICK_TYPE unsigned int32

  • main.c

 

  1. #include <main.h>
  2. TICK_TYPE GetTickDifference(TICK_TYPE currTick, TICK_TYPE prevTick)
  3. {
  4. return(currTick-prevTick);
  5. }

  6. void timer_1_tick(void)
  7. {
  8. //TODO: User Code
  9. }


  10. void main()
  11. {

  12. TICK_TYPE CurrentTick,PreviousTick;



  13. //Example program using Tick Timer
  14. CurrentTick = PreviousTick = get_ticks();

  15. while(TRUE)
  16. {
  17. CurrentTick = get_ticks();

  18. if(GetTickDifference(CurrentTick, PreviousTick) >= ((TICK_TYPE)TICKS_PER_SECOND*1)/1000)
  19. {
  20. timer_1_tick();
  21. PreviousTick = CurrentTick;
  22. }

  23. //TODO: User Code
  24. }

  25. }

 Then I need to add some codes to these existing source codes.

  •  main.h

 

  1. #include <30F2010.h>
  2. #device ICSP=1
  3. #use delay(crystal=20000000)

  4. #FUSES NOWDT //No Watch Dog Timer
  5. #FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled


  6. #use FIXED_IO( D_outputs=PIN_D1,PIN_D0 )

  7. #define LED1 PIN_D0
  8. #define LED2 PIN_D1


  9. #use timer(timer=1,tick=100us,bits=32,NOISR)

  10. #define TICK_TYPE unsigned int32


  • main.c
  1. #include <main.h>

  2. unsigned int16 count_1_ms=0, count_100_ms=0;

  3. TICK_TYPE GetTickDifference(TICK_TYPE currTick, TICK_TYPE prevTick)
  4. {
  5. return(currTick-prevTick);
  6. }

  7. void timer_1_tick(void)
  8. {
  9. //TODO: User Code
  10. count_1_ms++;
  11. if(count_1_ms>=100) {
  12. output_toggle(LED2);
  13. count_1_ms=0;
  14. count_100_ms++;
  15. }
  16. if(count_100_ms>=5){
  17. output_toggle(LED1);
  18. count_100_ms=0;
  19. }
  20. }


  21. void main()
  22. {

  23. TICK_TYPE CurrentTick,PreviousTick;



  24. //Example program using Tick Timer
  25. CurrentTick = PreviousTick = get_ticks();

  26. while(TRUE)
  27. {
  28. CurrentTick = get_ticks();

  29. if(GetTickDifference(CurrentTick, PreviousTick) >= ((TICK_TYPE)TICKS_PER_SECOND*1)/1000)
  30. {
  31. timer_1_tick();
  32. PreviousTick = CurrentTick;
  33. }

  34. //TODO: User Code
  35. }

  36. }

 It will blink LEDs connect to RD0 and RD1 at different rates.

 

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
RD0 and RD1 at different rates

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
RD0 and RD1 at different rates

 Click here to download its source file.

Timer 1 Interrupt Example Using Coder Generation Wizard

Timer1 module operates in many modes up to software configuration, internal, gated and external. We can write its source manually or even using the CCS PICC code generation wizard. 

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
Using Code Generation Wizard

Then it will generate a skeleton code below that we have to add more code manually.

  1. #include <main.h>

  2. #INT_TIMER1
  3. void timer1_isr(void)
  4. {

  5. }



  6. void main()
  7. {

  8. setup_timer1(TMR_INTERNAL | TMR_DIV_BY_1, 1000);

  9. enable_interrupts(INT_TIMER1);
  10. enable_interrupts(INTR_GLOBAL);

  11. while(TRUE)
  12. {
  13. //TODO: User Code
  14. }

  15. }

 Then I need to add more codes both in main function and Timer interrupt service routine "#INT_TIMER1".

 

  1. #include <main.h>

  2. unsigned int16 timer_1_counts=0;
  3. #INT_TIMER1
  4. void timer1_isr(void)
  5. {
  6. output_toggle(PIN_D0);
  7. timer_1_counts++;
  8. clear_interrupt(INT_TIMER1);
  9. }



  10. void main()
  11. {

  12. setup_timer1(TMR_INTERNAL | TMR_DIV_BY_256, 1000);

  13. enable_interrupts(INT_TIMER1);
  14. enable_interrupts(INTR_GLOBAL);

  15. while(TRUE)
  16. {
  17. //TODO: User Code
  18. if(timer_1_counts>=100){
  19. output_toggle(pin_d1);
  20. timer_1_counts=0;
  21. }
  22. }

  23. }

This source codes will blink pin RD0 and RD1 at different rates. Click here to download its source file.

Change Notify (CN) Interrupt

Change Notify Interrupt (CNI) allow the program to fast response to external event change. For instance a change from logic high to low or vice versa. There are two tactile switches connect to RC13(CN1) and RC14(CN0) respectively. There are no external pull up or pull down resistors. So you need to add more external components to detect input logic change requirement.

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
TABLE 8-2: INPUT CHANGE NOTIFICATION REGISTER MAP (BITS 15-0)

Fortunately the Change Notify Interrupt (CNI) come with internal pull-up enable feature that we can enable or disable it by software setting. The CNENx and CNPUx special register responsible for this task. 

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue) 

The program below demonstrate a simple use of Change Notify (CN) Interrupt of pin CN0(RC14). The LED connects to pin RD0 keeps blinking at the rate of 500ms in main program's loop. Whenever the CN0 input logic changes to logic low the CNI occurs. It will toggle the LED connects to pin RD1.

  • main.c 
  1. #include <main.h>

  2. /*CN Pull Up Enable Register*/
  3. #byte CNPU1=0x0C4;
  4. #bit CN0PU=CNPU1.0;
  5. /*CN Interrupt Enable Register*/
  6. #byte CNIEN1=0x0C0;
  7. #bit CN0EN=CNIEN1.0;

  8. /*Interrupt Service Routine for CN Interrupt*/
  9. #INT_CNI
  10. void cni_isr(void)
  11. {
  12. if(!input(CN0)) output_toggle(LED2);
  13. clear_interrupt(INT_CNI);
  14. }


  15. void main()
  16. {
  17. /*PortC As Inputs*/
  18. set_tris_c(0xFFFF);
  19. /*Turn On CN0 PullUp and CN0 Interrupt*/
  20. CN0PU=1;
  21. CN0EN=1;
  22. /*Enable Interrupt*/
  23. enable_interrupts(INTR_CN_PIN|PIN_C13);
  24. enable_interrupts(INTR_GLOBAL);
  25. clear_interrupt(INT_CNI);
  26. while(TRUE)
  27. {
  28. //TODO: User Code
  29. output_toggle(LED1);
  30. delay_ms(500);
  31. }

  32. }
  •  main.h
  1. #include <30F2010.h>
  2. #device ICSP=1
  3. #use delay(crystal=20000000)

  4. #FUSES NOWDT
  5. //No Watch Dog Timer
  6. #FUSES CKSFSM
  7. //Clock Switching is enabled, fail Safe clock monitor is enabled


  8. #use FIXED_IO( D_outputs=PIN_D1,PIN_D0 )

  9. #define CN1 PIN_C13
  10. #define CN0 PIN_C14
  11. #define LED1 PIN_D0
  12. #define LED2 PIN_D1



 I tested this demo program on my dsPIC30F2010 prototype board. It work fine and very fast. Click here to download this example program.

Now I use all tactile switches connect to RC13 and RC14 to generate Change Notification Interrupt (CNI). Every time the CN interrupts occur it will toggle the LEDs.

  • main.c

 

  1. #include <main.h>

  2. /*CN Pull Up Enable Register*/
  3. #byte CNPU1=0x0C4;
  4. #bit CN0PU=CNPU1.0;
  5. #bit CN1PU=CNPU1.1;
  6. /*CN Interrupt Enable Register*/
  7. #byte CNIEN1=0x0C0;
  8. #bit CN0EN=CNIEN1.0;
  9. #bit CN1EN=CNIEN1.1;

  10. /*Interrupt Service Routine for CN Interrupt*/
  11. #INT_CNI
  12. void cni_isr(void)
  13. {
  14. if(!input(CN0)) output_toggle(LED2);
  15. if(!input(CN1)) output_toggle(LED1);
  16. clear_interrupt(INT_CNI);
  17. }


  18. void main()
  19. {
  20. /*PortC As Inputs*/
  21. set_tris_c(0xFFFF);
  22. /*Turn On CN0 PullUp and CN0 and CN1 Interrupt*/
  23. CN0PU=1;
  24. CN0EN=1;
  25. CN1PU=1;
  26. CN1EN=1;
  27. /*Enable Interrupt*/
  28. //enable_interrupts(INTR_CN_PIN|PIN_C13);
  29. //enable_interrupts(INTR_CN_PIN|PIN_C14);
  30. enable_interrupts(INT_CNI);
  31. enable_interrupts(INTR_GLOBAL);
  32. clear_interrupt(INT_CNI);
  33. while(TRUE)
  34. {
  35. //TODO: User Code
  36. }

  37. }

I take some special registers of CN interrupt to use in this program because using the CCS PICC built-in library is not enough.

  • main.h
  1. #include <30F2010.h>
  2. #device ICSP=1
  3. #use delay(crystal=20000000)

  4. #FUSES NOWDT
  5. //No Watch Dog Timer
  6. #FUSES CKSFSM
  7. //Clock Switching is enabled, fail Safe clock monitor is enabled


  8. #use FIXED_IO( D_outputs=PIN_D1,PIN_D0 )

  9. #define CN1 PIN_C13
  10. #define CN0 PIN_C14
  11. #define LED1 PIN_D0
  12. #define LED2 PIN_D1




There are some bounce while pressing the tactile switches. So it's suitable to add and RC filter circuit to eliminate this noise. Using a software delay in the ISR is a good choice to bypass this noisy bouncing period.

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)

dsPIC30F2010 Prototype Board CCS PICC Examples (Continue)
 

Click here to download this program example.
 

Search This Blog

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (34) Analog Comparator (1) Arduino (16) ARM (13) AT89C52 (7) ATMega32 (58) ATMega644P (27) AVR (87) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (4) Display (133) Distance Sensor (3) ds1307 (10) DS18B20 (5) ds3231 (1) ds3232 (2) dsPIC (5) dsPIC30F1010 (3) dsPIC30F2010 (5) EEPROM (5) Environment Sensor (5) ESP32 (1) esp8266 (1) Graphical LCD (2) I2C (38) ILI9341 (1) Input/Output (75) Interrupt (22) Keil (5) Keypad (16) KS0108 (2) LCD (75) LM35 (3) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (10) PCD8544 (3) PCF8574 (10) PIC (108) PIC12F (3) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (13) SH1106 (3) Shift Register (13) Shift Registers (10) Software TWI (2) SPI (39) ST7735 (1) STM32 (11) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (5) STM32CubeIDE (13) STM32F103C8T6 (9) STM32F401CCU6 (1) SysTick (4) temperature sensor (13) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (8) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)