冰楓論壇

標題: PIC12F83 微型示波器 [打印本頁]

作者: 洪嵐峰    時間: 2023-4-9 09:46
標題: PIC12F83 微型示波器
以下是使用PIC12F83微控制器實現微型示波器的簡單電路和代碼示例。

需要的零件如下:

PIC12F83微控制器
16x2字符LCD顯示器
10K歐姆電位器
適當的電容和電阻
杜邦線等連接線
連接腳位如下:

PIC12F83        LCD顯示器
GP0        RS
GP1        RW
GP2        E
GP3        D4
GP4        D5
GP5        D6
GP6        D7
GP7        10K歐姆電位器
GP0        輸入信號
其中,10K歐姆電位器用於調節LCD的對比度。

代碼示例如下:


#include <pic12f83.h>
#include <stdio.h>

#define _XTAL_FREQ 20000000 //晶振頻率

#define LCD_RS GP0
#define LCD_RW GP1
#define LCD_E GP2
#define LCD_D4 GP3
#define LCD_D5 GP4
#define LCD_D6 GP5
#define LCD_D7 GP6

#define INPUT GP7

void Delay_us(unsigned int t)
{
    while (t--)
    {
        __delay_us(1);
    }
}

void Delay_ms(unsigned int t)
{
    while (t--)
    {
        __delay_ms(1);
    }
}

void LCD_Enable(void)
{
    LCD_E = 1;
    Delay_us(1);
    LCD_E = 0;
    Delay_us(1);
}

void LCD_Write4bit(unsigned char dat)
{
    LCD_D4 = (dat >> 0) & 0x01;
    LCD_D5 = (dat >> 1) & 0x01;
    LCD_D6 = (dat >> 2) & 0x01;
    LCD_D7 = (dat >> 3) & 0x01;
    LCD_Enable();
}

void LCD_WriteCmd(unsigned char cmd)
{
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_Write4bit(cmd >> 4);
    LCD_Write4bit(cmd);
    Delay_us(50);
}

void LCD_WriteData(unsigned char dat)
{
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_Write4bit(dat >> 4);
    LCD_Write4bit(dat);
    Delay_us(50);
}

void LCD_Init(void)
{
    Delay_ms(100);
    LCD_WriteCmd(0x02);
    LCD_WriteCmd(0x28);
    LCD_WriteCmd(0x0c);
    LCD_WriteCmd(0x06);
}

void ADC_Init(void)
{
    ANSEL = 0b10000000; // GP7 as analog input
    TRISIO = 0b10000000; // GP7 as input
    ADCON0 = 0b10001101; // ADC on, GP7 as input, right justified, Fosc/8
    ADCON1 = 0b00000000; // Vref+ = VDD, Vref- = VSS
}

unsigned int ADC_Read(void)
{
    ADCON0bits.GO_DONE = 1; // start conversion
    while (ADCON0bits.GO_DONE); // wait for completion
    return (ADRESH << 8| ADRESL) + ADRESL; // combine ADRESH and ADRESL
}

void LCD_Clear(void)
{
LCD_WriteCmd(0x01);
}

void LCD_SetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;

scss
Copy code
if (y == 0)
{
    addr = 0x00 + x;
}
else
{
    addr = 0x40 + x;
}

LCD_WriteCmd(addr | 0x80);
}

void main(void)
{
unsigned int adc_val;
char buf[17];

OSCCON = 0b01111010; // internal oscillator, 8MHz
LCD_Init();
ADC_Init();
LCD_Clear();
LCD_SetCursor(0, 0);
LCD_WriteData('V');
LCD_WriteData('i');
LCD_WriteData('n');
LCD_SetCursor(0, 1);
LCD_WriteData('0');
LCD_WriteData('0');
LCD_WriteData('.');
LCD_WriteData('0');
LCD_WriteData('0');
LCD_WriteData('V');

while (1)
{
    adc_val = ADC_Read();
    sprintf(buf, "%04u.%02uV", adc_val * 5 / 1023, adc_val * 500 / 1023 % 100);
    LCD_SetCursor(3, 1);
    LCD_WriteData(buf[0]);
    LCD_WriteData(buf[1]);
    LCD_WriteData(buf[2]);
    LCD_SetCursor(4, 1);
    LCD_WriteData(buf[3]);
    LCD_WriteData(buf[4]);
    LCD_SetCursor(6, 1);
    LCD_WriteData(buf[5]);
    LCD_WriteData(buf[6]);
    LCD_WriteData(buf[7]);
    Delay_ms(100);
}
}



此代碼使用單個模擬輸入(GP7)讀取輸入信號,並使用LCD顯示輸入電壓。
在LCD上,第一行顯示“Vin”,第二行顯示輸入電壓的值。
代碼中使用的ADC轉換電壓範圍為0V至5V,並將其轉換為1023個步驟。
使用sprintf函數將ADC值轉換為字符串,然後將其寫入LCD顯示器。
此外,該程序還使用了延遲函數來控制LCD刷新速度。




歡迎光臨 冰楓論壇 (https://bingfong.com/) Powered by 冰楓