PDA

View Full Version : PIC16F676 ! hiển thị điện áp DC trên LED


badandan
01-04-2010, 01:50 PM
sơ đồ mạch :http://www.coolcircuit.com/project/meter/circuit.GIF

minh
ai giúp mình lập trình cho PIC được ko ?

mình đang làm đồ án môn học nhưng còn phần hiển thị điện áp DC 0->15V trên LED 7 đoạn thì mình ko bít pải làm sao ?

mong anh em giúp nhá

trongtuan_1109
21-05-2010, 04:07 PM
Bạn có thể nói rõ hơn 1 chút yêu cầu của bạn xem,hiển thị 0->15 tại sao fải dùng 3 con LED 7 đoạn nhỉ?Mình nghĩ 2 con thôi chứ
À các bạn cho mình hỏi nhìn vào LED sao mình biết được là LED đó nối Anode chung hay Cathode chung vậy?

manhdktd
03-07-2010, 11:25 AM
chỉ cần 2 led thôi
mình chưa hiểu ý bạn lắm.nếu chỉ cần hiển thị điện áp thì ta chỉ cần tách thành hàng chục và đơn vị rồi sử dụng thuật toán quét led là đươc.
còn nếu phải đo điện áp rồi qua adc để diển thị thì phải hạ áp xuống.

manhdktd
04-07-2010, 11:05 AM
nếu bạn làm xong rồi thì post lên cho mọi người học tập đi

thaithienanh
07-07-2010, 04:10 AM
Thực chất đầu vào ADC mạch trên là một cầu chia áp điện trở mục đích là đưa nguồn điện có hiệu điện thế lớn về mức tham chiếu 5V, từ tỉ lệ giá trị điện trở biết trước và điện áp ADC nắm bắt được ta sẽ xác định được hiệu điện thế của nguồn điện được đo > quét led segment :)

Chúc vui.

nhctdhbk
12-07-2010, 05:29 PM
đay là đoạn code mình tìm thấty ở trên mạng cho cái sơ đồ mà bạn badandan đã đưa ra. tuy nhiên khi mo phỏng bằng protues mình thấy led ko hiển thị được. Bác nào pro xem giúp sai ở chỗ nào cái?
#include <16F676.h>
#device adc=10
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,BROWNOUT,NOMCLR
#use delay (clock=4000000) // 4MHz clock

#rom 0x3ff={0x3444}

#byte PORTA = 0x05
#byte PORTC = 0x07
#byte TRISA = 0x85
#byte TRISC = 0x87

#define SPORTA PORTA
#define SPORTC PORTC

#define TICKS_BETWEEN_INTERRUPTS 5000 //5000
#define INTERRUPT_OVERHEAD 35
#define TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))

const char SegCode[11] = {0x40,0x57,0x22,0x06,0x15,0x0C,0x08,0x56,0x00,0x04 ,0xFF};
// 0 1 2 3 4 5 6 7 8 9
const char Column[3] = {0x02,0x01,0x04};
static char Segment[3] = {0x7f,0x7f,0x7f};
static unsigned char ColCount=0x00;

void CPU_SETUP(void);
void Display(void);
void HTO7S(unsigned int32 Num);

byte i;
unsigned int32 result;

#INT_TIMER1
void Timer1(void)
{
set_timer1(TMR1RESET);
Display();
}

void main()
{
unsigned char i;

CPU_SETUP();

while(true)
{
result=0;
for (i=0;i<20;i++)
{
set_adc_channel(3);
delay_ms(1);
result=result+read_adc();
}
//result = 0x3fe;
HTO7S(result/20);
delay_ms(200);
}

}

void CPU_SETUP()
{

setup_comparator(NC_NC_NC_NC); // not use comparator module
setup_adc_ports( sAN3 | VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64);
TRISA=0b00011000;
PORTA=0x27;
TRISC=0b00000000;
PORTC=0x37;


setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(TMR1RESET);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
}

//-------------------------------------
// Display routine
//-------------------------------------
void Display()
{
PORTA = 0b00100111; // off all digits column and Segment G
PORTC = 0b00111111; // off segment a-f
delay_cycles(2);


if (ColCount>=3)
ColCount=0;

SPORTC = Segment[ColCount];
SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
ColCount++;
}

//--------------------------------------
// Convet HEX 2 byte to 7-Segment code
//--------------------------------------
void HTO7S(unsigned int32 Num)
{

unsigned int32 res;


Segment[0]=SegCode[30*Num/10230];
if (Segment[0]==0x40)
Segment[0]=0xFF;

res = 30*Num%10230;
Segment[1]=SegCode[10*res/10230];
res=10*res%10230;
Segment[2]=SegCode[10*res/10230];
}

manhdktd
13-07-2010, 01:06 PM
code này khó hiểu quá.mong các cao nhân chỉ giáo

thanhhavdt
13-07-2010, 11:23 PM
Here are some notes from my quick perusal of the code.

1. The format of the 11 element array:
Each element corresponds to the bit pattern for the corresponding digit. Element 0 = pattern for numeral 0, Element 1 = pattern for numeral 1 etc., Element 10 = pattern for blank.
Bit 0=Segment A
Bit 1=Segment F
Bit 2=Segment E
Bit 3=Segment B
Bit 4=Segment D
Bit 5=Segment C
Bit 6=Segment G
If the bit is zero, the segment is ON; if the bit is one, the segment is OFF.

2. The ADC produces a 10 bit number: 0 to 1023

3. The HTO7S routine scales this into a 0 to 30.0 number and separates the 3 digits using integer division and the mod operator. The scaling is done by multiplying by 30 and then dividing by 10230. This gives a value of 0 to 3 for the first digit as expected. The trick here is that because it is integer arithmetic, it's important to multiply by 30, to scale up the number before dividing by 10230. Otherwise, the fractional part would be lost, and hence accuracy would also be lost for subsequent digits. However, as far as I can see the result would be the same if he multiplied by 3 and then divided by 1023. The calculation of the next two digits is done using a similar method. First the previous highest digit is stripped off using the % (mod) operator. You just need to work through the math to satisfy yourself that this works.

A check is done to see if the leading digit is zero (bit pattern for 0 is 0x40):
if (Segment[0]==0x40)
Segment[0]=0xFF;
And if so it is blanked by changing the segment code to 0xFF
4. The "Display" routine does a bit more juggling of the segment codes that were generated in the HTO7S routine, because, while bits 0 to 5 go directly to the corresponding bits in PORTC, bit 6 has to go to bit 5 of PORTA and the 3 column select bits (for multiplexing) are also sent out in bits 0, 1, and 2 of PORTA. That's what this does:
SPORTA = ((Segment[ColCount] & 0b01000000)>>1) | (Column[ColCount]^0x07);
This step strips off all except bit 6 (the & operator) then shifts it right to bit 5 position. The column select lines are set by the remainder of the step. The column select is inverted by Exclusive ORing with 0x07, and then ORed into the bits 0 to 2. All of this then goes out to PORTA.

The way the display routine is set up, only one digit is sent out each time through the routine. So, it has to execute three times before all 3 digits are displayed. This is no problem since the routine is called each time through the main program loop.

Hope this helps.

haudktd
08-12-2011, 11:00 AM
nhờ các bác giúp về phần lý thuyết: pic 16f676 thankyou!