冰楓論壇

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

[討論] PIC16F690

[複製鏈接]

2609

主題

0

好友

1003

積分

金牌會員

Rank: 6Rank: 6

UID
373967
帖子
9008
主題
2609
精華
0
積分
1003
楓幣
0
威望
980
存款
35891
贊助金額
0
推廣
0
GP
1205
閱讀權限
70
在線時間
460 小時
註冊時間
2023-1-12
最後登入
2024-12-22

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

跳轉到指定樓層
1
發表於 2023-5-2 18:54:19 |只看該作者 |倒序瀏覽
製作USB電壓電流顯示器
需要以下零件:

PIC16F690 微控制器
LCD 顯示屏
INA219 電流感測器模組
10K 歐姆電阻器
4.7K 歐姆電阻器
0.1uF 電容
5V 電源
USB 接口
杜邦線和面包板

連接腳位:

連接 INA219 電流感測器模組到 PIC16F690 的 I2C 接口上。模組的 SDA 線連接到 PIC16F690 的 RC4 腳位,SCL 線連接到 RC3 腳位。
連接 LCD 顯示屏到 PIC16F690 的端口 B 上。顯示屏的 RS 引腳連接到 RB0 腳位,E 引腳連接到 RB1 腳位,D4-D7 引腳分別連接到 RB4-RB7 腳位。
在 PIC16F690 的 VDD 和 VSS 腳位間加上 0.1uF 的電容以穩定電源。
連接 10K 歐姆電阻器到 PIC16F690 的 RA5 腳位,作為 USB 電源的檢測引腳。
連接 4.7K 歐姆電阻器到 RA2 腳位,以啟用 PIC16F690 的內部溫度感測器。
程式碼:

以下是 PIC16F690 的範例程式碼,可用於顯示 USB 電源的電壓和電流:


#include <pic16f690.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INA219_ADDRESS 0x40
#define INA219_REG_CONFIG 0x00
#define INA219_REG_SHUNT_VOLTAGE 0x01
#define INA219_REG_BUS_VOLTAGE 0x02
#define INA219_REG_CURRENT 0x04
#define INA219_REG_POWER 0x03
#define INA219_REG_CALIBRATION 0x05
#define INA219_CAL_VALUE 8192
#define INA219_CURRENT_LSB 0.01
#define LCD_RS PORTBbits.RB0
#define LCD_EN PORTBbits.RB1
#define LCD_D4 PORTBbits.RB4
#define LCD_D5 PORTBbits.RB5
#define LCD_D6 PORTBbits.RB6
#define LCD_D7 PORTBbits.RB7
#define LCD_CMD_CLEAR 0x01
#define LCD_CMD_HOME 0x02
#define LCD_CMD_ENTRY_MODE 0
#define LCD_CMD_INIT1 0x33
#define LCD_CMD_INIT2 0x32
#define LCD_CMD_INIT3 0x28
#define LCD_CMD_DISPLAY_ON 0x0C
#define LCD_CMD_CURSOR_OFF 0x0E

int current_mA = 0;
int voltage_mV = 0;

void init();
void lcd_init();
void lcd_command(unsigned char command);
void lcd_char(unsigned char data);
void lcd_string(const char *str);
void delay(unsigned int d);
void i2c_init();
unsigned int i2c_read(unsigned char reg);
void i2c_write(unsigned char reg, unsigned int value);
void read_ina219();
void main() {
init();
while(1) {
read_ina219();
char buffer[16];
sprintf(buffer, "U=%d.%02dV I=%d.%02dA", voltage_mV/1000, voltage_mV%1000/10, current_mA/1000, current_mA%1000/10);
lcd_command(LCD_CMD_CLEAR);
lcd_string(buffer);
delay(100);
}
}

void init() {
// 設置 I/O 方向和模式
TRISAbits.TRISA2 = 1;
TRISAbits.TRISA5 = 1;
TRISB = 0x00;
ANSEL = 0x00;
ANSELH = 0x00;
OSCCON = 0b01110000;

lcd_init();
i2c_init();
}

void lcd_init() {
lcd_command(LCD_CMD_INIT1);
delay(5);
lcd_command(LCD_CMD_INIT1);
delay(1);
lcd_command(LCD_CMD_INIT1);
lcd_command(LCD_CMD_INIT2);
lcd_command(LCD_CMD_INIT3);
lcd_command(LCD_CMD_DISPLAY_ON);
lcd_command(LCD_CMD_CURSOR_OFF);
lcd_command(LCD_CMD_CLEAR);
}

void lcd_command(unsigned char command) {
LCD_RS = 0;
LCD_EN = 1;
LCD_D4 = (command >> 4) & 0x01;
LCD_D5 = (command >> 5) & 0x01;
LCD_D6 = (command >> 6) & 0x01;
LCD_D7 = (command >> 7) & 0x01;
LCD_EN = 0;
delay(1);
LCD_EN = 1;
LCD_D4 = command & 0x01;
LCD_D5 = (command >> 1) & 0x01;
LCD_D6 = (command >> 2) & 0x01;
LCD_D7 = (command >> 3) & 0x01;
LCD_EN = 0;
delay(1);
}

void lcd_char(unsigned char data) {
LCD_RS = 1;
LCD_EN = 1;
LCD_D4 = (data >> 4) & 0x01;
LCD_D5 = (data >> 5) & 0x01;
LCD_D6 = (data >> 6) & 0x01;
LCD_D7 = (data >> 7) & 0x01;
LCD_EN = 0;
delay(1);
LCD_EN = 1;
LCD_D4 = data & 0x01;
LCD_D5 = (data >> 1) & 0x01;
LCD_D6 = (data >> 2) & 0x01;
LCD_D7 = (data >> 3) & 0x01;
LCD_EN = 0;
delay(1);
}

void lcd_string(const char *str) {
while(*str) {
lcd_char(*str++);
}
}

void delay(unsigned int d) {
while(d--) {
__delay_ms(1);
}
}

void i2c_init() {
SSPSTAT = 0b10000000;
SSPCON = 0b00101000;
SSPADD = 39;
}


void read_ina219() {

i2c_write(0x00, 0b1000000000000111);

unsigned int voltage = i2c_read(0x02);
voltage = (voltage << 8) | i2c_read(0x01);
voltage = voltage >> 3;
voltage_mV = voltage * 4;

unsigned int current = i2c_read(0x04);
current = (current << 8) | i2c_read(0x03);
current_mA = current / 10;
}

void i2c_write(unsigned char reg, unsigned int value) {
SSPCON2bits.SEN = 1;
while(SSPCON2bits.SEN);
SSPBUF = 0b10000000;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPBUF = reg;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPBUF = value >> 8;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPBUF = value & 0xFF;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPCON2bits.PEN = 1;
while(SSPCON2bits.PEN);
}

unsigned int i2c_read(unsigned char reg) {
unsigned int value;
SSPCON2bits.SEN = 1;
while(SSPCON2bits.SEN);
SSPBUF = 0b10000000;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPBUF = reg;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
SSPCON2bits.RSEN = 1;
while(SSPCON2bits.RSEN);
SSPBUF = 0b10000001;
while(SSPSTATbits.R_nW);
while(SSPIF == 0);
SSPIF = 0;
value = SSPBUF;
SSPCON2bits.ACKDT = 0;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN);
value = (value << 8) | SSPBUF;
SSPCON2bits.PEN = 1;
while(SSPCON2bits.PEN);
return value;
}


void main() {

lcd_init();
i2c_init();

lcd_string("USB Voltage:");
lcd_set_cursor(0, 1);
lcd_string("USB Current:");

while(1) {

read_ina219();

lcd_set_cursor(13, 0);
lcd_string(" ");
lcd_set_cursor(13, 0);
lcd_string(itoa(voltage_mV));
lcd_string("mV");
lcd_set_cursor(13, 1);
lcd_string(" ");
lcd_set_cursor(13, 1);
lcd_string(itoa(current_mA));
lcd_string("mA");
delay(500);
}
}
收藏收藏0 推0 噓0


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

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

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

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

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

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

GMT+8, 2024-12-22 16:44

回頂部