- UID
- 373967
- 帖子
- 9008
- 主題
- 2609
- 精華
- 0
- 積分
- 1003
- 楓幣
- 0
- 威望
- 980
- 存款
- 35891
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 70
- 在線時間
- 460 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2024-12-22
|
製作PIC16F690控制
18650八槽充電器所需的零件:
PIC16F690微控制器
8個18650電池槽
8個MOSFET (N溝道)
8個1K歐姆電阻
8個紅色LED和8個綠色LED
8個10K歐姆電阻
一個LM317電壓穩壓器
4個10uF電容
1個16MHz晶振
2個22pF電容
1個熱敏電阻
1個4位七段數碼管
1個MAX7219芯片
1個12V電源適配器
1個5V穩壓電源
1個IC座
連接線和電線
以下是PIC16F690的引腳分配:
RC0 - 紅色LED1
RC1 - 綠色LED1
RC2 - MOSFET1
RC3 - 紅色LED2
RC4 - 綠色LED2
RC5 - MOSFET2
RC6 - 紅色LED3
RC7 - 綠色LED3
RA0 - MOSFET3
RA1 - MOSFET4
RA2 - MOSFET5
RA3 - MOSFET6
RA4 - 熱敏電阻
RA5 - MOSFET7
MCLR - 編程引腳
OSC1 - 晶振引腳
OSC2 - 晶振引腳
RB0 - 紅色LED4
RB1 - 綠色LED4
RB2 - MOSFET8
RB3 - 七段數碼管的CLK引腳
RB4 - 七段數碼管的DIN引腳
RB5 - 七段數碼管的CS引腳
RB6 - 5V穩壓電源引腳
RB7 - 12V電源引腳
以下是PIC16F690的程序代碼:
#include <pic16f690.h>
#include <stdlib.h>
#include <htc.h>
#define _XTAL_FREQ 16000000
#define CHARGING_VOLTAGE 4200
#define THERMISTOR_RESISTANCE 10000
#define MAX7219_CS PORTBbits.RB5
#define MAX7219_DIN PORTBbits.RB4
#define MAX7219_CLK PORTBbits.RB3
float convertADCtoVoltage(unsigned int adcValue) {
return (float)adcValue * 5.0 / 1024.0;
}
unsigned int convertVoltagetoADC(float voltage) {
return (unsigned int)(voltage * 1024.0 / 5.0);
}
float readTemperature() {
unsigned int adcValue = 0;
float voltage = 0.0;
float resistance = 0.0;
float temperature = 0.0;
adcValue = ADRESH;
adcValue <<= 8;
adcValue |= ADRESL;
voltage = convertADCtoVoltage(adcValue);
resistance = THERMISTOR_RESISTANCE * (5.0 / voltage - 1);
temperature = log(resistance / 10000.0);
temperature /= 3950.0;
temperature += 1.0 / (25.0 + 273.15);
temperature = 1.0 / temperature - 273.15;
return temperature;
}
void initADC() {
ADCON0bits.ADON = 1;
ADCON1 = 0b00000000;
ADCON0 = 0b00000101;
}
void initGPIO() {
TRISC = 0b00000000;
TRISA = 0b11111000;
TRISB = 0b00001000;
PORTC = 0b00000000;
PORTA = 0b00000111;
PORTB = 0b00000000;
}
void initTimer0() {
T0CS = 0;
PSA = 0;
PS2 = 1;
PS1 = 1;
PS0 = 1;
TMR0 = 0;
TMR0IE = 1;
}
void initSPI() {
SSPSTAT = 0b00000000;
SSPCON = 0b00100000;
}
void initSevenSegmentDisplay() {
MAX7219_CS = 1; //
T
sendSPI(0x0C, 0x01);
sendSPI(0x09, 0xFF);
sendSPI(0x0A, 0x0F);
sendSPI(0x0B, 0x07);
}
void sendSPI(unsigned char address, unsigned char data) {
MAX7219_CS = 0;
SSPBUF = address;
while(!SSPSTATbits.BF);
SSPBUF = data;
while(!SSPSTATbits.BF);
MAX7219_CS = 1;
}
void displayNumber(unsigned int number) {
int i = 0;
unsigned char digit = 0;
unsigned char data = 0;
for(i = 0; i < 8; i++) {
digit = number % 10;
number /= 10;
switch(digit) {
case 0:
data = 0x7E;
break;
case 1:
data = 0x30;
break;
case 2:
data = 0x6D;
break;
case 3:
data = 0x79;
break;
case 4:
data = 0x33;
break;
case 5:
data = 0x5B;
break;
case 6:
data = 0x5F;
break;
case 7:
data = 0x70;
break;
case 8:
data = 0x7F;
break;
case 9:
data = 0x7B;
break;
}
sendSPI(i + 1, data);
}
}
void chargeLED() {
static int led = 0;
if(led == 0) {
PORTC = 0b00000100;
led = 1;
} else if(led == 1) {
PORTC = 0b00001000;
led = 0;
}
}
void finishLED() {
static int led = 0;
if(led == 0) {
PORTC = 0b00000100;
led = 1;
} else if(led == 1) {
PORTC = 0b00000000;
led = 0;
}
}
float readBatteryVoltage(unsigned char channel) {
unsigned int adcValue = 0;
float voltage = 0.0;
switch(channel) {
case 0:
ANSELbits.ANS0 = 1;
break;
case 1:
ANSELbits.ANS1 = 1;
break;
case 2:
ANSELbits.ANS2 = 1;
break;
case 3:
ANSELbits.ANS3 = 1;
break;
case 4:
ANSELbits.ANS4 = 1;
break;
case 5:
ANSELbits.ANS5 = 1;
break;
case 6:
ANSELbits.ANS6 = 1;
break;
case 7:
ANSELbits.ANS7 = 1;
break;
}
ADCON0bits.CHS = channel;
ADCON0bits.ADON = 1;
__delay_us(10);
ADCON0bits.GO = 1;
while(ADCON0bits.GO);
adcValue = (ADRESH << 8) + ADRESL;
voltage = adcValue * 5.0 / 1023.0;
ADCON0bits.ADON = 0;
switch(channel) {
case 0:
ANSELbits.ANS0 = 0;
break;
case 1:
ANSELbits.ANS1 = 0;
break;
case 2:
ANSELbits.ANS2 = 0;
break;
case 3:
ANSELbits.ANS3 = 0;
break;
case 4:
ANSELbits.ANS4 = 0;
break;
case 5:
ANSELbits.ANS5 = 0;
break;
case 6:
ANSELbits.ANS6 = 0;
break;
case 7:
ANSELbits.ANS7 = 0;
break;
}
return voltage;
}
void selectSlot(unsigned char slot) {
CHG_SEL_0 = 0;
CHG_SEL_1 = 0;
CHG_SEL_2 = 0;
CHG_SEL_3 = 0;
CHG_SEL_4 = 0;
CHG_SEL_5 = 0;
CHG_SEL_6 = 0;
CHG_SEL_7 = 0;
switch(slot) {
case 0:
CHG_SEL_0 = 1;
break;
case 1:
CHG_SEL_1 = 1;
break;
case 2:
CHG_SEL_2 = 1;
break;
case 3:
CHG_SEL_3 = 1;
break;
case 4:
CHG_SEL_4 = 1;
break;
case 5:
CHG_SEL_5 = 1;
break;
case 6:
CHG_SEL_6 = 1;
break;
case 7:
CHG_SEL_7 = 1;
break;
}
}
void charge(unsigned char slot) {
float voltage = 0.0
selectSlot(slot);
voltage = getVoltage(slot);
if(voltage >= MAX_VOLTAGE) {
CHG_EN = 0;
__delay_ms(100);
CHG_EN = 1;
return;
}
CHG_EN = 1;
while(voltage < MAX_VOLTAGE) {
voltage = getVoltage(slot);
__delay_ms(100);
}
CHG_EN = 0;
__delay_ms(100);
CHG_EN = 1;
}
void main() {
TRISAbits.TRISA0 = 1;
TRISAbits.TRISA1 = 1;
TRISAbits.TRISA2 = 1;
TRISAbits.TRISA3 = 1;
TRISAbits.TRISA4 = 1;
TRISAbits.TRISA5 = 1;
TRISAbits.TRISA6 = 1;
TRISAbits.TRISA7 = 1;
TRISCbits.TRISC0 = 0;
TRISCbits.TRISC1 = 0;
TRISCbits.TRISC2 = 0;
TRISCbits.TRISC3 = 0;
TRISCbits.TRISC4 = 0;
TRISCbits.TRISC5 = 0;
TRISCbits.TRISC6 = 0;
TRISCbits.TRISC7 = 0;
ADCON1bits.ADFM = 1;
ADCON1bits.ADCS = 0b100;
ADCON0bits.ADON = 0;
selectSlot(0);
while(1) {
charge(0);
__delay_ms(1000);
charge(1);
__delay_ms(1000);
charge(2);
__delay_ms(1000);
charge(3);
__delay_ms(1000);
charge(4);
__delay_ms(1000);
charge(5);
__delay_ms(1000);
charge(6);
__delay_ms(1000);
charge(7);
__delay_ms(1000);
}
} |
|