——基于PIC16F877A的电子秤设计)
首先简要描述一下实现的功能使用电位器采用电阻分压的形式来改变电阻上的电压以此来模拟电子秤上重量的变化。使用PIC16F877A的AD转换端口测量电阻上的电压用此数据来代替物体重量。同时用LCD1602显示器将所测量的重量显示在屏幕上。整体电路图如下所示首先简单介绍一下LCD1602模块该模块具体的信息网上有很多资源可以参考RS数据或命名选择端。0:命令 1:数据RW读写控制端。 0:写 1:读E使能端D0-D7数据端写指令的时候应该RS0,RW0,D0-D7data,E1,延时一段时间E0;写数据的时候应该RS1,RW0,D0-D7data,E1,延时一段时间E0;接下来详细介绍PIC16F877A的AD转换功能直接看官方文档的介绍从中可以知道对于28脚系列的 器件有5路模拟输入端对于40/44脚的器件有8路模拟输入端。输入的模拟电压会被转换为10位的数字量也就是AD的有效位数为10位。AD转换的参考电压是软件可配置的。与AD转换模块密切相关的寄存器为ADRESH: AD转换结果的高位寄存器ADRESL: AD转换结果的低位寄存器ADCON0: AD转换模块的控制寄存器ADCON1AD转换模块的控制寄存器ADCON0寄存器各个位的信息如下所示该寄存器的第6-7位和ADCON1的ADCS2位一起用于选择AD转换的时钟速率第5-3位用于选择AD转换的通道第2位AD转换的状态位。当手动将该位置1时开启AD转换。AD转换结束后硬件自动将该位置0。如果AD转换没有完成那么该位一直为1.第1位保留没有作用。第0位AD模块启用位。为1表示打开AD模块启用AD。ADCON1寄存器各个位的信息如下所示该寄存器第7位控制AD转换结果的格式。1表示结果右对齐左边空出来的位为0。0表示左对齐右边空出的位为0.该寄存器第6位和上面的ADCPN0一起控制AD转换的时钟速率。5-4位未实现读为0.3-0位用于控制AD转换引脚的工作模式以及AD转换模块的参考电压。基础知识铺垫完毕以后就可以开始准备编写代码了。首先是配置好PIC16F877A单片机的配置位然后要包含一定的头文件其中头文件“ee302lcd.h”里面包含的是和液晶屏LCD1602相关的函数。然后定义一个全局字符串用于存放测到的重量信息也可以理解为测到的模拟电压值再定义一个变量用于保存AD转换值接下来定义一个开启AD转换的函数最后就是主函数了。主函数里面包含了AD转换的配置模式以及LCD1602的初始化函数、显示函数等等。全部main.c如下// CONFIG #pragma config FOSC XT // Oscillator Selection bits (XT oscillator) #pragma config WDTE OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN OFF // Brown-out Reset Enable bit (BOR disabled) #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) #include xc.h #include ee302lcd.h // Include LCD header file #include stdio.h // Include Standard I/O header file unsigned char outString[5]; //character array for LCD string int adc_value; void do_adc(void) { __delay_us(30); //Acqusition time delay set to 30us (19.7us) GO_nDONE1; //Start ADC conversion while(GO_nDONE)continue; //Wait until conversion finishes adc_value ADRESH; //Pass ADRESH value to adc_value variable sprintf(outString,%dkg,ADRESH); //显示光照强度 光照阈值 运行时间 Lcd8_Write_String(outString); //Lcd8_Set_Cursor(2,0); } void main(void) { Lcd8_Init(); // Required initialisation of LCD to 8-bit mode TRISA0x04; // Set PORTA bit 3 as input for AN2 ADCON0 0b01010001; // ADCS1:ADCS0 set to 0:1 for Tosc x8 (Fosc/8) // Channel 2 // ADC On ADCON1 0b00000010; // Left justified result // ADCS2 0 for Tosc x8 (Fosc/8) // RA2/AN2 selected as analog input // Vref : Vdd Vref- : Vss // AN7, AN6 and AN5 selected for Digital I/O for LCD while(1) { Lcd8_Clear(); //clear LCD do_adc(); __delay_ms(100); } }需要完整工程代码和仿真的请看评论区。