【问题标题】:MPLAB XC8 Compiler PIC18F452 Multiplexed Seven Segment Display Code working properlyMPLAB XC8 编译器 PIC18F452 多路复用七段显示代码正常工作
【发布时间】:2018-03-30 00:04:09
【问题描述】:

我目前正在编写涉及 MPLAB XC8 编译器 PIC18F452 和多路复用七段显示器的代码。我想使用连接到 PIC18F452 的 PORTB 的引脚 RB2 和 RB3 的两个按钮来增加和减少变量“计数”,并在此显示器上显示从 0 到 99 的数字。原理图和代码如下所示。

这段代码的功能相对来说是这样的,我不认为原理图是我看到的问题的罪魁祸首,字节数组也不是不正确的,因为在使用带有 1 的数组时我能够看到每个数字分段展示。

尝试使用下图所示的这种多路复用方案时会出现问题。我可以在七段显示器上成功显示两个数字,但是执行此代码时出现奇怪的异常。一方面,我似乎无法在任一显示器上显示数字 1、4 和偶尔 7,但是当这个数字没有显示时,显示器是空白的,当再次按下按钮时,下一个数字会按预期显示。

例如:

对于编号规则,显示屏显示如下数字: 9... 10... 11... 12 13... 14...等等...

34.... 35... 36... 37....

不确定问题出在哪里,并且调试不顺利...任何帮助将不胜感激。

Schematic for Multiplexed 7 Segment Display

#define _XTAL_FREQ 10000000
#include <xc.h>
#include <stdlib.h>
#define Digit1 PORTBbits.RB1 //variable to sink current to PNP base
#define Digit2 PORTBbits.RB2 //variable to sink current to PNP base
#define Switch1 PORTBbits.RB4 //switch decrement variable
#define Switch2 PORTBbits.RB3 //switch increment variable
#define Pressed1 1 //pressed is high
#define Pressed2 1 //pressed is high
void initialize();
void segment1 (void);
void segment2 (void);
void buttonPress(void);
void delay_ms(unsigned int);
void sendPattern1(unsigned char pattern);
void sendPattern2(unsigned char pattern3);
unsigned char rotateLeft(unsigned char pattern, int no);
unsigned char MSD, LSD, count=0;

主要代码

void main(void){
  initialize();
  Digit1 = 0;
  Digit2 = 0;
  while(1){
  buttonPress();
  MSD = count/10 ;  
  segment1();
  Digit2 = 1;
  delay_ms(10); // Delay for 10 ms
  Digit2 = 0;
  LSD = count%10; 
  segment2();
  Digit1 = 1;
  delay_ms(10); // Delay for 10 ms
  Digit1 = 0;
   }
    return;
}

从阵列中索引最高有效数字和最低有效数字的功能将被发送到端口以吸收低电流以用于公共阳极显示。

void segment1(void){
unsigned char segArrayC[]={0b11000000,0b11111001,0b00100100, 
0b00110000,0b00011001,0b00010010, 
0b00000010,0b11111000,0b00000000,0b00011000};
 unsigned char pattern;
    pattern = segArrayC[MSD];
    sendPattern1(pattern);
    return;
}
void segment2(void){
unsigned char segArrayD[]= {0b11000000,0b11111001,0b00100100,
0b00110000,0b00011001,0b00010010,0b00000010,
0b11111000,0b00000000,0b00011000};
unsigned char pattern3;
     pattern3 = segArrayD[LSD];
     sendPattern2(pattern3);
     return;
}

按键代码

void buttonPress(void){
  if (Switch1 == Pressed1) {
        ++count;
        delay_ms(100);
    }
 if (Switch2 == Pressed2) {
        --count;
        delay_ms(100);
    }

 if(count>=99||count<0)
 {
     count=0; 
     delay_ms(100);
 }
  return;
}

将数组中的字节向左旋转两个位置以显示在端口上的功能

/** Rotate pattern to the left 'no' number of bits
 */
unsigned char rotateLeft(unsigned char pattern, int no) {
    return (((pattern << no) & 0xFF) | (pattern >> (8-no)));
}

将索引数组字符输出到 PORTC 和 PORTB 引脚的函数

void sendPattern1(unsigned char pattern) {
    // Send pattern to appropriate port pins
    unsigned char pattern2;
    PORTC = pattern;
    pattern2=rotateLeft(pattern, 2);
    PORTB = pattern2;
    return;
}
void sendPattern2(unsigned char pattern3) {
    unsigned char pattern4;
    PORTC = pattern3;
    pattern4=rotateLeft(pattern3, 2);
    PORTB = pattern4;
    return;
}

延时功能

    void delay_ms(unsigned int n){
    while (--n) _delay(2500);
}

初始化要使用的引脚(0 输出,1 输入)

void initialize() {
     TRISC = 0;
     TRISBbits.TRISB0 = 0;
     TRISBbits.TRISB1 = 0;
     TRISBbits.TRISB2 = 0;
     TRISBbits.TRISB4 = 1;
     TRISBbits.TRISB3 = 1;
     PORTC = 0x00;
     PORTB = 0x00;
}

【问题讨论】:

  • 函数sendPattern1()sendPattern2()在功能上没有区别。是有意的吗?
  • 我正在考虑将它们分别放入段 1() 和段 2() 函数中。除了更好地组织代码之外,没有真正的理由将它们作为单独的函数来实现。
  • 为什么要使用两个端口,PORTB 和 PORTC? unsigned char count; ... if (count&lt;0) 应该给你一个警告。

标签: c microcontroller pic mplab xc8


【解决方案1】:

在 sendPattern() 中,您将旋转位模式写入 PORTB。 这会干扰设置共阳极控制。所以你只能看到两个数字,如果两个右手段都打开了。根据您的原理图,您应该写一个 0 来打开共阳极。试试这个:

void main()
{
     static const unsigned char segArray[]= 
     { 0b11000000, 0b11111001, 0b00100100, 0b00110000, 0b00011001,
       0b00010010, 0b00000010, 0b11111000, 0b00000000, 0b00011000
     };
     TRISC = 0; //PortC all OUTPUT
     PORTC = 0xFF; //PortC all HIGH = IDLE = LED_OFF

     TRISBbits.TRISB0 = 0; //Output unused
     TRISBbits.TRISB1 = 0; //Output Digit1
     TRISBbits.TRISB2 = 0; //Output Digit2
     TRISBbits.TRISB4 = 1; //Input: Switch PLUS
     TRISBbits.TRISB3 = 1; //Input: Switch MINUS 

     PORTB = 0x00;
     unsigned char count=0;
     for(;;)
     {
        //Handle buttons
        if (Switch1 && count<99) 
        {
           ++count;
           delay_ms(100);
        }
        if (Switch2 && count > 0) 
        {
           --count;
           delay_ms(100);
        }

        //Write high digit
        PORTC = segArray[count/10];  
        Digit2 = 0;
        delay_ms(10); // Delay for 10 ms
        Digit2 = 1;

        //Write low digit
        PORTC = segArray[count%10];  
        Digit1 = 0;
        delay_ms(10); // Delay for 10 ms
        Digit1 = 1;
   }
}

【讨论】:

    猜你喜欢
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    相关资源
    最近更新 更多