A simple 8-bit PIC16F84A micro-controller can do a lot of stuff as it has only 1kB of ROM, 68 bytes of RAM, 64 bytes of EEPROM two digital I/O port, one timer, etc. Some electronic engineer make an LC meter or a frequency meter with a dozen of components using this small embedded controller. Using the Assembly language is suitable for this micro-controller because it has a little RAM and SFR. Furthermore it has only 35 Assembly instructions to use.
Simulating Program At Start Up |
In this example I use this micro-controller with a 16x2 character LCD, a DS18B20 digital thermometer, switches, relay, etc. It could be a temperature controlled DC or AC switch. We can use it control an AC fan on and off. However I could find an AC lamp in Proteus. So I replace with a DC/AC lamp.
PIC16F84A In P-DIP Package |
I use a free version of XC8 v2.36 in MPLABX IDE v1.51 to make its firmware. It does not have restriction but without technical support and code optimization. It should be effective as the program that was written using Assembly language.
A preset temperature value is stored in EEPROM. It's adjustable. It's read once when the program start. Whenever we adjust the preset temperature it will change its value in EEPROM. The current value in program is also updated.
The main program loop continuously get the temperature data from DS18B20, check whether there's a switch pressing.
#include<xc.h> #define _XTAL_FREQ 4000000 // PIC16F84A Configuration Bit Settings // CONFIG #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator) #pragma config WDTE = ON // Watchdog Timer (WDT enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled) #pragma config CP = OFF // Code Protection bit (Code protection disabled) #define DQ RA4 #define DQ_DIR TRISA4 unsigned char ow_reset(void){ unsigned char presence; DQ_DIR=0; DQ=0; __delay_us(480); DQ=1; __delay_us(70); DQ_DIR=1; presence=DQ; __delay_us(425); return presence; } unsigned char readBit(void){ DQ_DIR=0; DQ=0; DQ_DIR=1; __delay_us(15); return DQ; } void writeBit(char bitVal){ DQ_DIR=0; DQ=0; if(bitVal==1) DQ=1; __delay_us(104); DQ=1; } unsigned char readByte(void){ unsigned char i; unsigned char value=0; for(i=0;i<8;i++){ if(readBit()) value|=0x01<<i; __delay_us(96); } return value; } void writeByte(char val){ unsigned char i; unsigned char temp; for(i=0;i<8;i++){ temp=val>>i; temp&=0x01; writeBit(temp); } __delay_us(104); } __EEPROM_DATA(0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07); __EEPROM_DATA(0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71); void main(void){ unsigned char LSB,MSB; unsigned char get[9]; unsigned int temp; /*PORT B AND A AS OUTPUT*/ PORTB=0x00; TRISB=0x00; PORTA=0x00; TRISA=0x00; //Select Internal Timer Clock Source OPTION_REGbits.T0CS=0; //Assign The Prescaler To WDT OPTION_REGbits.PSA=1; //Select 1:128 Prescaler OPTION_REGbits.PS=0x07; //Clear Watch Dog Timer CLRWDT(); //Initiate A First 1-Wire Read ow_reset(); writeByte(0xCC); writeByte(0x44); __delay_us(104); ow_reset(); writeByte(0xCC); writeByte(0xBE); for(int i=0;i<9;i++) get[i]=readByte(); __delay_ms(1000); CLRWDT(); while(1){ ow_reset(); writeByte(0xCC); writeByte(0x44); __delay_us(104); ow_reset(); writeByte(0xCC); writeByte(0xBE); for(int i=0;i<9;i++) get[i]=readByte(); MSB=get[1]; LSB=get[0]; temp=(MSB<<8)+LSB; temp>>=4; LSB=0x0F&LSB; if(LSB^0x08) LSB=0; else LSB=5; //temp&=0x00FF; //PORTB=temp; __delay_ms(10); PORTA=0x00; PORTB=eeprom_read(temp/100); if(temp>=100) RA0=1; __delay_ms(5); PORTA=0x00; PORTB=eeprom_read((temp%100)/10); if(temp>=10) RA1=1; __delay_ms(5); PORTA=0x00; PORTB=eeprom_read(temp%10)|0x80; RA2=1; __delay_ms(5); PORTA=0x00; PORTB=eeprom_read(LSB); RA3=1; __delay_ms(5); CLRWDT(); } }
It requires 90.9% of program space, and 63.2% of data space. I added a Watch Dog Timer (WDT) reset to keep track of operation of program. Once it's halted ,the WDT will reset the software.
Resource Usage Of PIC16F84A |
Temperature Reaches The Preset Value, The Output Relay On |
Press SW4 To Show EEPROM Preset Value |
Press SW3 To Increase Its Preset Value |
Press SW4 To Decrease Its Preset Value |
This small project could be use in some areas. I don't have hardware experiment or PCB design for this project because my PIC16F84A was burned a long time ago. Click here to download source file for this project.