数字显示不正确,无法控制特定引脚的输出
Digits not displayed properly, Unable to control output at particular pin
我正在尝试将我的输入显示在微控制器 ATmega16 到 7 段显示器上。
我在 http://www.avr-tutorials.com/projects/atmega16-based-digital-clock 上找到了以下代码,但是当我实现它时,它不起作用。我得到一个 波动的输出 即 我无法控制特定引脚的输出。
我有两个输入 temp1 和 temp2,我想在三个 7 段显示器上显示它们中的每一个。另外,我没有使用引脚 2 和 3,因为它们是中断引脚,我在其他地方使用过它们。 Pin0,1,4,5,6,7 被使用。
添加一些延迟后代码工作正常,否则输出会在随机引脚生成。
即我想从 PIND1 显示的输出显示在所有引脚上,
我的代码:
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define SegDataPort PORTC
#define SegDataPin PINC
#define SegDataDDR DDRC
#define SegCntrlPort PORTD
#define SegCntrlPin PIND
#define SegCntrlDDR DDRD
/*
* Function Description:
* Encode a Decimal Digit 0-9 to its Seven Segment Equivalent.
*
* Function Arguments:
* digit - Decimal Digit to be Encoded
* common - Common Anode (0), Common Cathode(1)
* SegVal - Encoded Seven Segment Value
*
* Connections:
* Encoded SegVal is return in the other G-F-E-D-C-B-A that is A is the least
* significant bit (bit 0) and G bit 6.
*/
unsigned char DigitTo7SegEncoder(int digit, unsigned char common)
{
unsigned char SegVal;
switch(digit)
{
case 0: if(common == 1) SegVal = 0b00111111;
else SegVal = ~0b00111111;
break;
case 1: if(common == 1) SegVal = 0b00000110;
else SegVal = ~0b00000110;
break;
case 2: if(common == 1) SegVal = 0b01011011;
else SegVal = ~0b01011011;
break;
case 3: if(common == 1) SegVal = 0b01001111;
else SegVal = ~0b01001111;
break;
case 4: if(common == 1) SegVal = 0b01100110;
else SegVal = ~0b01100110;
break;
case 5: if(common == 1) SegVal = 0b01101101;
else SegVal = ~0b01101101;
break;
case 6: if(common == 1) SegVal = 0b01111101;
else SegVal = ~0b01111101;
break;
case 7: if(common == 1) SegVal = 0b00000111;
else SegVal = ~0b00000111;
break;
case 8: if(common == 1) SegVal = 0b01111111;
else SegVal = ~0b01111111;
break;
case 9: if(common == 1) SegVal = 0b01101111;
else SegVal = ~0b01101111;
}
return SegVal;
}
int main(void)
{
int temp1,temp2;
//Suppose my input is 105 and 210, i.e. temp1=105 and temp2=210;
// it contains other information also, not required here
SegDataDDR = 0xFF;
SegCntrlDDR = 0xF3;
SegCntrlPort = 0xF3;
SegDataPort = 0x00;
while(1){
SegDataPort = DigitTo7SegEncoder(temp1%10,1);
SegCntrlPort = ~0x01;
SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1);
SegCntrlPort = ~0x02;
SegDataPort = DigitTo7SegEncoder(temp1/100,1);
SegCntrlPort = ~0x10;
SegDataPort = DigitTo7SegEncoder(temp2%10,1);
SegCntrlPort = ~0x20;
SegDataPort = DigitTo7SegEncoder((temp2/10)%10,1);
SegCntrlPort = ~0x40;
SegDataPort = DigitTo7SegEncoder(temp2/100,1);
SegCntrlPort = ~0x80;
}}
假设这些 7 段组件内部不包含任何时序逻辑,这就是实际发生的情况:
SegDataPort = DigitTo7SegEncoder(temp1%10,1); // You write the data
SegCntrlPort = ~0x01; // You enable the first 7-segment component
// Then without any delay...
SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1); // You write other data
SegCntrlPort = ~0x02; // You enable the second component
// The without any delay...
所以实际上 7 段组件会在短时间内同时显示前后数字。
这个呢? (只是一个伪代码)
SegCntrlPort = 0xFF; // hide everything
SetDataPort = ... value1 ...;
SegCntrlPort = ~0x01; // show it
WaitForAWhile();
SegCntrlPort = 0xFF; // hide everything to avoid unwanted transitions
SetDataPort = ... value2 ...;
SegCntrlPort = ~0x02; // show it
WaitForAWhile();
以此类推
您没有将 DDR 设置为在任何地方输出。要用作输出的引脚必须将 DDRx 中的相应位设置为 1。否则它仍然是输入引脚。
输入引脚将显示输出,但电流较低且上升沿较慢。用 LCD 吸收该电流可能会导致电压下降。
我正在尝试将我的输入显示在微控制器 ATmega16 到 7 段显示器上。
我在 http://www.avr-tutorials.com/projects/atmega16-based-digital-clock 上找到了以下代码,但是当我实现它时,它不起作用。我得到一个 波动的输出 即 我无法控制特定引脚的输出。 我有两个输入 temp1 和 temp2,我想在三个 7 段显示器上显示它们中的每一个。另外,我没有使用引脚 2 和 3,因为它们是中断引脚,我在其他地方使用过它们。 Pin0,1,4,5,6,7 被使用。
添加一些延迟后代码工作正常,否则输出会在随机引脚生成。 即我想从 PIND1 显示的输出显示在所有引脚上,
我的代码:
#include <avr/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define SegDataPort PORTC
#define SegDataPin PINC
#define SegDataDDR DDRC
#define SegCntrlPort PORTD
#define SegCntrlPin PIND
#define SegCntrlDDR DDRD
/*
* Function Description:
* Encode a Decimal Digit 0-9 to its Seven Segment Equivalent.
*
* Function Arguments:
* digit - Decimal Digit to be Encoded
* common - Common Anode (0), Common Cathode(1)
* SegVal - Encoded Seven Segment Value
*
* Connections:
* Encoded SegVal is return in the other G-F-E-D-C-B-A that is A is the least
* significant bit (bit 0) and G bit 6.
*/
unsigned char DigitTo7SegEncoder(int digit, unsigned char common)
{
unsigned char SegVal;
switch(digit)
{
case 0: if(common == 1) SegVal = 0b00111111;
else SegVal = ~0b00111111;
break;
case 1: if(common == 1) SegVal = 0b00000110;
else SegVal = ~0b00000110;
break;
case 2: if(common == 1) SegVal = 0b01011011;
else SegVal = ~0b01011011;
break;
case 3: if(common == 1) SegVal = 0b01001111;
else SegVal = ~0b01001111;
break;
case 4: if(common == 1) SegVal = 0b01100110;
else SegVal = ~0b01100110;
break;
case 5: if(common == 1) SegVal = 0b01101101;
else SegVal = ~0b01101101;
break;
case 6: if(common == 1) SegVal = 0b01111101;
else SegVal = ~0b01111101;
break;
case 7: if(common == 1) SegVal = 0b00000111;
else SegVal = ~0b00000111;
break;
case 8: if(common == 1) SegVal = 0b01111111;
else SegVal = ~0b01111111;
break;
case 9: if(common == 1) SegVal = 0b01101111;
else SegVal = ~0b01101111;
}
return SegVal;
}
int main(void)
{
int temp1,temp2;
//Suppose my input is 105 and 210, i.e. temp1=105 and temp2=210;
// it contains other information also, not required here
SegDataDDR = 0xFF;
SegCntrlDDR = 0xF3;
SegCntrlPort = 0xF3;
SegDataPort = 0x00;
while(1){
SegDataPort = DigitTo7SegEncoder(temp1%10,1);
SegCntrlPort = ~0x01;
SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1);
SegCntrlPort = ~0x02;
SegDataPort = DigitTo7SegEncoder(temp1/100,1);
SegCntrlPort = ~0x10;
SegDataPort = DigitTo7SegEncoder(temp2%10,1);
SegCntrlPort = ~0x20;
SegDataPort = DigitTo7SegEncoder((temp2/10)%10,1);
SegCntrlPort = ~0x40;
SegDataPort = DigitTo7SegEncoder(temp2/100,1);
SegCntrlPort = ~0x80;
}}
假设这些 7 段组件内部不包含任何时序逻辑,这就是实际发生的情况:
SegDataPort = DigitTo7SegEncoder(temp1%10,1); // You write the data
SegCntrlPort = ~0x01; // You enable the first 7-segment component
// Then without any delay...
SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1); // You write other data
SegCntrlPort = ~0x02; // You enable the second component
// The without any delay...
所以实际上 7 段组件会在短时间内同时显示前后数字。
这个呢? (只是一个伪代码)
SegCntrlPort = 0xFF; // hide everything
SetDataPort = ... value1 ...;
SegCntrlPort = ~0x01; // show it
WaitForAWhile();
SegCntrlPort = 0xFF; // hide everything to avoid unwanted transitions
SetDataPort = ... value2 ...;
SegCntrlPort = ~0x02; // show it
WaitForAWhile();
以此类推
您没有将 DDR 设置为在任何地方输出。要用作输出的引脚必须将 DDRx 中的相应位设置为 1。否则它仍然是输入引脚。
输入引脚将显示输出,但电流较低且上升沿较慢。用 LCD 吸收该电流可能会导致电压下降。