冰楓論壇

 找回密碼
 立即註冊
ads_sugarbook
搜索
查看: 644|回覆: 0
打印 上一主題 下一主題

[討論] PIC16F628

[複製鏈接]

2609

主題

0

好友

947

積分

高級會員

Rank: 4

UID
373967
帖子
7479
主題
2609
精華
0
積分
947
楓幣
1455
威望
927
存款
26000
贊助金額
0
推廣
0
GP
1205
閱讀權限
50
在線時間
409 小時
註冊時間
2023-1-12
最後登入
2024-5-10

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-26 06:42:00 |只看該作者 |倒序瀏覽
製作變頻機需要的零件包括:

PIC16F628 微控制器
晶振(通常使用4MHz的晶振)
22pF環氧陶瓷電容(用於晶振的穩定)
10k歐姆電阻(用於重置電路)
10uF電解電容(用於供電電路的濾波)
100nF環氧陶瓷電容(用於降噪和穩定)
2個按鈕(用於調整頻率)
16x2液晶顯示器(用於顯示頻率和訊息)
10k歐姆可變電阻(用於調整頻率)
電源供應器(通常使用9V電池或直流電源)
PIC16F628的連結腳位如下:

VDD:供電腳,接5V或3.3V電源
VSS:接地腳,接地
RA0 - RA5:數位輸入/輸出腳,可設置為輸入或輸出模式
RB0 - RB7:數位輸入/輸出腳,可設置為輸入或輸出模式
OSC1:晶振輸入腳,連接到晶振的一端
OSC2:晶振輸出腳,連接到晶振的另一端
MCLR:重置腳,通常連接一個10k歐姆電阻到VDD

程式碼如下:(這只是基礎的程式碼,需要根據具體需求進行修改)


// PIC16F628 變頻機程式碼

#include <htc.h>
#include <stdio.h>

// 配置設定
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF);

// 定義變量和常量
#define _XTAL_FREQ 4000000 // 使用4MHz的晶振
#define LCD_RS RA0
#define LCD_EN RA1
#define LCD_D4 RA2
#define LCD_D5 RA3
#define LCD_D6 RA4
#define LCD_D7 RA5
#define BUTTON1 RB0
#define BUTTON2 RB1
#define POT RB2
#define LCD_LINE1 0x80
#define LCD_LINE2 0xC0

// 函數聲明
void LCD_Init(void);
void LCD_Write_Char(char);
void LCD_Write_String(char *);
void LCD_Cmd(char);
void LCD_Clear(void);
void LCD_Set_Cursor(char, char);
void ADCvoid ADC_Init(void);
unsigned int ADC_Read(unsigned char);

// 主函數
void main()
{
unsigned int adc_value;
char freq_str[16];
int freq = 1000; // 初始頻率為1kHz

TRISB0 = 1; // 設置按鈕為輸入模式
TRISB1 = 1;
TRISB2 = 1; // 設置可變電阻為輸入模式
ANSELH = 0; // 設置數位腳

LCD_Init(); // 初始化液晶顯示器
ADC_Init(); // 初始化ADC

while(1)
{
    // 讀取按鈕和可變電阻的值
    if(!BUTTON1)
    {
        freq -= 10;
        if(freq < 100) freq = 100;
        __delay_ms(200);
    }
    if(!BUTTON2)
    {
        freq += 10;
        if(freq > 10000) freq = 10000;
        __delay_ms(200);
    }
    adc_value = ADC_Read(2);

    // 計算頻率
    freq = 100 + adc_value * 39 / 1023;

    // 將頻率轉換為字符串
    sprintf(freq_str, "Freq: %d Hz", freq);

    // 在液晶顯示器上顯示頻率和訊息
    LCD_Set_Cursor(1, 1);
    LCD_Write_String(freq_str);
    LCD_Set_Cursor(2, 1);
    LCD_Write_String("Press button to adj.");

    // 延遲一段時間
    __delay_ms(100);
}
}

// 初始化液晶顯示器
void LCD_Init()
{
TRISA = 0x00;
TRISB = 0x00;
LCD_Cmd(0x02);
LCD_Cmd(0x28);
LCD_Cmd(0x0C);
LCD_Cmd(0x06);
LCD_Cmd(0x01);
}

// 寫入字符到液晶顯示器
void LCD_Write_Char(char data)
{
LCD_RS = 1;
PORTB = data;
LCD_EN = 1;
__delay_us(4);
LCD_EN = 0;
__delay_us(40);
}

// 寫入字符串到液晶顯示器
void LCD_Write_String(char *str)
{
while(*str)
{
LCD_Write_Char(*str++);
}
}

// 發送命令到液晶顯示器
void LCD_Cmd(char command)
{
LCD_RS = 0;
PORTB = command;
LCD_EN = 1;
__delay_us(4);
LCD_EN = 0;
__delay_us(40);
}

// 清空液晶顯示器
void LCD_Clear()
{
LCD_Cmd(0x01);
}

// 設置液晶顯示器游標位置
void LCD_Set_Cursor(char row, char column)
{
char address;
if(row == 1)
{
address = LCD_LINE1 + column - 1;
}
else
{
address = LCD_LINE2 + column - 1;
}

LCD_Cmd(0x80 | address);
}

// 初始化ADC
void ADC_Init(void)
{
ADCON0 = 0x81; // 設置ADC模塊
ADCON1 = 0x80; // 設置ADC輸入電壓範圍
__delay_us(20); // 等待模塊啟動
}

// 讀取ADC值
unsigned int ADC_Read(unsigned char channel)
{
ADCON0 &= 0xC7; // 清除ADC通道選擇
ADCON0 |= channel << 3; // 設置ADC通道
__delay_us(20); // 等待轉換完成
GO_nDONE = 1; // 啟動轉換
while(GO_nDONE); // 等待轉換完成
return (ADRESH << 8) + ADRESL; // 返回ADC值
}

// 設置PWM
void PWM_Init(void)
{
TRISC2 = 0; // 設置RC2為輸出模式
CCP1CON = 0x0C; // 設置PWM模式
PR2 = 124; // 設置TMR2的週期為4us
T2CON = 0x01; // 啟動TMR2
}

// 設置PWM頻率
void PWM_Set_Frequency(unsigned int frequency)
{
unsigned int pwm_period;
pwm_period = (_XTAL_FREQ / (4 * frequency)) - 1;
CCPR1L = pwm_period >> 2;
CCP1CON = (CCP1CON & 0xCF) | ((pwm_period & 0x03) << 4);
}

// 設置PWM佔空比
void PWM_Set_Duty_Cycle(unsigned char duty_cycle)
{
unsigned int pwm_duty_cycle;
pwm_duty_cycle = ((unsigned int)duty_cycle * PR2) / 100;
CCPR1L = pwm_duty_cycle >> 2;
CCP1CON = (CCP1CON & 0xCF) | ((pwm_duty_cycle & 0x03) << 4);
}

// 延遲一段時間
void __delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i = 0; i < ms; i++)
{
for(j = 0; j < 165; j++);
}
}

void __delay_us(unsigned int us)
{
unsigned int i, j;
for(i = 0; i < us; i++)
{
for(j = 0; j < 2; j++);
}
}

// 腳位連接
// RA0 - 不使用
// RA1 - 不使用
// RA2 - 不使用
// RA3 - 不使用
// RA4 - 不使用
// RA5 - 不使用
// RA6 - 不使用
// RA7 - 不使用

// RB0 - 按鈕1,接VCC上拉
// RB1 - 按鈕2,接VCC上拉
// RB2 - 可變電阻,接GND和VCC之間,中間接ADC

// RC0 - 不使用
// RC1 - 不使用
// RC2 - PWM
// RC3 - LCD RS
// RC4 - LCD E
// RC5 - LCD D4
// RC6 - LCD D5
// RC7 - LCD D6

// 主程序
void main()
{
unsigned int frequency = 1000; // 初始頻率為1kHz
unsigned char duty_cycle = 50; // 初始佔空比為50%
unsigned int adc_value;
char lcd_buffer[16];

// 初始化
OSCCON = 0x72; // 設置FOSC為8MHz
TRISB = 0x03; // 設置RB0和RB1為輸入模式
ADC_Init(); // 初始化ADC
PWM_Init(); // 初始化PWM
PWM_Set_Frequency(frequency); // 設置PWM頻率
PWM_Set_Duty_Cycle(duty_cycle); // 設置PWM佔空比
LCD_Init(); // 初始化LCD

// 主循環
while(1)
{
    // 按鈕1按下,增加頻率
    if(!RB0)
    {
        frequency += 100;
        if(frequency > 10000) frequency = 10000;
        PWM_Set_Frequency(frequency);
        sprintf(lcd_buffer, "Freq: %4dHz", frequency);
        LCD_Write_String(lcd_buffer, 0x80);
        __delay_ms(200);
    }
    // 按鈕2按下,減少頻率
    if(!RB1)
    {
        frequency -= 100;
        if(frequency < 100) frequency = 100;
        PWM_Set_Frequency(frequency);
        sprintf(lcd_buffer, "Freq: %4dHz", frequency);
        LCD_Write_String(lcd_buffer, 0x80);
        __delay_ms(200);
    }
    // 讀取ADC值,設置佔空比
    adc_value = ADC_Read(2);
    duty_cycle = adc_value >> 6;
    PWM_Set_Duty_Cycle(duty_cycle);
    sprintf(lcd_buffer, "Duty: =%%", duty_cycle);
    LCD_Write_String(lcd_buffer, 0xC0);
    __delay_ms(20);
}
}

這是變頻機程序,可以根據按鈕和可變電阻的變化調整PWM的頻率和佔空比,並將頻率和佔空比顯示在LCD上。

收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1骰子
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-5-10 11:21

回頂部