pia-468x60

pia-728x90

Friday, April 29, 2022

ATMega16 two-digit multiplexing display and counting example

Display multiplexing is very common for most microcontroller programming and interfacing. In usual, a controller could drive up to 8 digits before we can see its display flickering. In this programming example, I use only two digits of 7-Segment display. Because it's easy to build the circuit with a  little of source codes.

ATMega16 two-digit multiplexing display example
Program simulation in Proteus

Controller keeps track of counting an external pulse generated by SW1 switch pressing. The maximum press counting is 60 before it rolls down to 0. The display will become flicker whenever the input switch has a longer press duration, but it's not longer than 250ms.

  1. /*
  2.  * mux2Ssd.c
  3.  *
  4.  * Created: 5/25/2022 7:20:40 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 4000000UL
  11. #include <util/delay.h>
  12.  
  13. int main(void)
  14. {
  15. //common cathode
  16. unsigned char SSD[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  17. unsigned char cnt=0;
  18. //PortC output
  19. DDRC=0xFF;
  20. //PD7 input
  21. DDRD&=~(1<<7);
  22. //Turn on PD7
  23. PORTD|=(1<<7);
  24. while (1)
  25. {
  26. //Display processing
  27. PORTD&=~(1<<0);
  28. PORTD&=~(1<<1);
  29. PORTC=SSD[cnt/10];
  30. PORTD|=(1<<0);
  31. _delay_ms(3);
  32.  
  33. PORTD&=~(1<<0);
  34. PORTD&=~(1<<1);
  35. PORTC=SSD[cnt%10];
  36. PORTD|=(1<<1);
  37. _delay_ms(3);
  38.  
  39. //Input Testing
  40. if ((PIND&0x80)==0)
  41. {
  42. //while((PIND&0x80)==0);
  43. cnt++;
  44. _delay_ms(250);
  45. }
  46. if(cnt>=60) cnt=0;
  47. }
  48. }
  49.  
  50.  

Click here to download source file.

ATMega16 two-digit multiplexing display and counting example
Schematic diagram

Thursday, March 31, 2022

A DIY Timer/Scheduler and temperature controller using PIC16F876A

Introduction

A timer is useful in any task that requires a specific time or a duration that the target device will turn on and off. It is easily found at low price. For electronic hobbyists, a timer can easily be created using a typical timer IC NE555 with other dozen of components.

Here I design a timer using a small microcontroller - PIC16F876A. It's suitable to handle timing setting, displaying, controlling, and scheduling. 

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Main menu of this timer

This timer can handle the following tasks:

  1. Main menu - displaying date/time, and temperature
  2. Date/Time setting
  3. Short 16 hours timer
  4. Temperature setting for an output relay
  5. Scheduling daily on time of timer relay

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Day of Week Adjust

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Time Adjust

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Date Adjust

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Short timer up to 16 hours



A DIY Timer/Scheduler and temperature controller using PIC16F876A
Temperature Adjusting for output relay

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Daily On Time Adjusting

Design

Firmware

I use MicroC Pro PIC to program this device. The operation of this device become abnormal whenever I try to add more function in C source code. So I tried to optimize, reduce, and test this project as much as I can to make the operation more stable.

Listing below is the source code for v1.2 of this project.

  1.  
  2. #include "board.h"
  3.  
  4. void main() {
  5. LCD_Set();
  6. DS1307_Init();
  7. T_Init();
  8. TMR0_SETUP();
  9. SCH_READ();
  10. while(1){
  11. Menu_Scan();
  12. Selector();
  13. SCH_RUN();
  14. }
  15. }

We can only see a dozen lines of code, as they are separated in different files. Click here to download firmware and design file.

Hardware

I designed this project using Proteus 8. This program also allow us to simulate.

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Schematic

Circuit board is very simple. It can be made using toner transfer method.

A DIY Timer/Scheduler and temperature controller using PIC16F876A
PCB design view
A DIY Timer/Scheduler and temperature controller using PIC16F876A
Copper track

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Top silk


A DIY Timer/Scheduler and temperature controller using PIC16F876A
Design view in 3D

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Idle

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Top Side

A DIY Timer/Scheduler and temperature controller using PIC16F876A
Bottom Side



Monday, January 31, 2022

Atmega16 external interrupt programming example

Atmega16 has up to 21 interrupt sources. Here I will discuss only the external interrupt of this controller. External interrupt consist of three source sources:

  1. INT0 - External interrupt request 0
  2. INT1 - External interrupt request 1, and
  3. INT2 - External interrupt request 2.

First I will show how to use INT0 source. It has four sense that determine whether the interrupt is triggering. It is the Interrupt Sense Control register bits of the MCU Control Register (MCUCR).

Atmega16 external interrupt programming example
MCU Control Register (MCUCR)

Atmega16 external interrupt programming example
 Interrupt Sense Control register bits

The General Interrupt Control Register (GICR) turn on and off these external interrupt source, including the INT0 source.

Atmega16 external interrupt programming example
General Interrupt Control Register – GICR

They also have their corresponding interrupt flag in the General Interrupt Flag Control (GIFR).

Atmega16 external interrupt programming example
General Interrupt Flag Control (GIFR)

There are three bit corresponding to INTF1, INTF0, and INTF2. These bits will be cleared after the Interrupt Service Routine (ISR) executed. Optionally the programmer can clear any flag by setting it. However it is uncommon from most of microcontrollers.

In C programming the interrupt is very easy to program that I will show it in this programming example.

In this example I use only the INT0 source. The interrupt sense is the falling edge of INT0, as I will select it in program. Each time the INT0 occurs, and output LED connects to PD7 will toggle.

Atmega16 external interrupt programming example
Schematic Diagram

The source code is very simple. It contains a little lines of code.

  1. /*
  2.  * int0Example1.c
  3.  *
  4.  * Created: 5/27/2022 6:45:11 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #include <avr/interrupt.h>
  11.  
  12. int main(void)
  13. {
  14. //PortD output
  15. DDRD=0xFF;
  16. //RD2 input
  17. DDRD&=~(1<<2);
  18. //Turn on RD2
  19. PORTD|=(1<<2);
  20. //Select falling edge of INT0
  21. MCUCR|=(1<<ISC01);
  22. //Enable INT0 request
  23. GICR|=(1<<INT0);
  24. //Enable interrupt
  25. sei();
  26. //Clear Flag
  27. GIFR|=(1<<INTF0);
  28. while (1)
  29. {
  30. }
  31. }
  32.  
  33. //Interrupt Service Routine - ISR
  34. ISR(INT0_vect){
  35. //Toggle PD7
  36. PORTD^=0x80;
  37. }
  38.  

Click here to download it source file.

Labels