简体   繁体   English

MPLAB XC8编译器PIC18F452复用七段显示代码正常工作

[英]MPLAB XC8 Compiler PIC18F452 Multiplexed Seven Segment Display Code working properly

I am currently working on a code involving the MPLAB XC8 Compiler, PIC18F452 with a Multiplexed Seven Segment Display. 我目前正在处理涉及MPLAB XC8编译器PIC18F452的代码,该代码具有多路七段显示。 I want to use two pushbuttons connected to pins RB2 and RB3 of PORTB of the PIC18F452 to increment and decrement a variable "count" and display this number from 0 to 99 on this display. 我想使用两个按钮连接到PIC18F452的PORTB的RB2和RB3引脚RB2和RB3,以递增和递减变量“ count”,并在此显示屏上显示从0到99的数字。 Schematic and code is show below. 原理图和代码如下所示。

This code relatively functions as it is, and I do not believe the schematic is to blame for the issues I am seeing, nor is the byte array not correct as I am able to see each number when using the array with a 1 segment display. 该代码按原样运行,我不认为原理图应归咎于我所遇到的问题,字节数组也不正确,因为当我将数组与1段显示一起使用时,我能够看到每个数字。

The issue arrises when trying to use this multiplexing scheme shown in the below figure. 尝试使用下图所示的多路复用方案时,会出现此问题。 I can successfully display two numbers on the seven segment displays, but there are strange anomalies present when executing this code. 我可以在七个段显示器上成功显示两个数字,但是执行此代码时会出现奇怪的异常现象。 For one, I seem to not be able to display the number 1, 4 and occasionally 7 on either display, but when this digit does not show the display is blank, and when the button is again pushed the next number is shown as expected. 对于其中一个,我似乎无法在任一显示屏上都显示数字1、4和偶尔显示7,但是当该数字不显示时,该显示为空白,并且再次按下该按钮时,将按预期显示下一个数字。

for example: 例如:

The display shows the numbers as follows for number sequences: 9... 1 0... 11 ... 1 2 1 3... 14 ... ect... 显示屏上显示的数字如下所示:9 ... 1 0 ... 11 ... 1 2 1 3 ... 14 ...等...

or 要么

3 4 .... 35... 36... 3 7 .... 3 4 .... 35 ... 36 ... 3 7 ....

Not sure where the issues lies, and debugging is not going well... any help would be appreciated. 不确定问题出在哪里,调试不顺利...任何帮助将不胜感激。

Schematic for Multiplexed 7 Segment Display 7段多路复用显示原理图

#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;

Main code 主要代号

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;
}

Functions to index Most Significant Digit and Least Significant Digit from array to be sent to the ports to sink current low for common annode display. 用于索引阵列中最高有效数字和最低有效数字的索引,以发送到端口以降低电流,以降低公共阳极显示的电流。

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;
}

Button Press Code 按钮按下代码

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;
}

Function to rotate bytes in array two places to left to be displayed on PORTs 将数组中的字节向左旋转两个位置以在PORT上显示的功能

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

Functions to output indexed array char to PORTC and PORTB pins 用于将索引数组char输出到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;
}

Delay Function 延迟功能

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

Initialize pins to be used (0 output, 1 input) 初始化要使用的引脚(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;
}

In sendPattern() you write a rotated bit pattern to PORTB. 在sendPattern()中,将旋转的位模式写入PORTB。 This interferes with the setting the common anode control. 这会干扰共阳极控制的设置。 So you see both digits only, if both right hand segments are turned on. 因此,如果同时打开了两个右侧部分,则只能看到两个数字。 According your schematic you should write a 0 to turn on the common anode. 根据原理图,您应该写一个0来打开共阳极。 Try this: 尝试这个:

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;
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM