冰楓論壇

標題: PIC16F690 [打印本頁]

作者: 洪嵐峰    時間: 2023-5-2 19:27
標題: PIC16F690
製作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);
}
}




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