|
|
楼主 |
发表于 2026-10-13 15:05:30
|
显示全部楼层
大神说的是杂点是因为使用PWM的原因吗?
麻烦看看程序,要怎么改
#include <STC8H.H>
#include "intrins.h"
#define u16 unsigned int
#define u8 unsigned char
sbit R1 =P2^0; //蓝色数据1
sbit G1 =P2^1; //绿色数据1
sbit b1 =P2^2; //红色数据1
sbit R2 =P2^3; //蓝色数据2
sbit G2 =P2^4; //绿色数据2
sbit b2 =P2^5; //红色数据2
sbit CLK =P3^6; //ICN2037时钟信号
sbit LE =P5^1; //ICN2037锁存信号
sbit OE =P3^4; //点阵屏显示片选信号
sbit IA =P4^0; //行控制线A
sbit IB =P4^1; //行控制线B
sbit IC =P4^2; //行控制线C
sbit ID =P4^3; //行控制线D
sbit IEN =P4^4; //行控制线E(控制上半屏和下半屏)
sbit SPI_SS = P5^4;
sbit SPI_SI = P1^3;
sbit SPI_SO = P1^4;
sbit SPI_SCK = P1^5;
sbit LED1 = P5^3;
sbit LED2 = P0^5;
sbit LED3 = P0^6;
#define BUF_LENGTH 4096 //缓存空间是4096字节
#define BUF_LENGTL 4096
#define idex1 (BUF_LENGTH) //SPI缓冲长度
#define idex2 (BUF_LENGTL) //SPI缓冲长度
volatile u16 SPI_Cnt ; //SPI计数
volatile bit spi_frame = 0;//缓存转换标志
xdata u8 SpiBuff1[idex1];//128*32行=4096字节缓存
xdata u8 SpiBuff2[idex2];
u16 ADC_temp;
//行扫描函数
void scan(u8 Hang)
{
PWMB_ENO = 0x00; //关显示
switch(Hang)
{
case 0: IA=0;IB=0;IC=0;ID=0;IEN=0;break;
case 1: IA=1;IB=0;IC=0;ID=0;IEN=0;break;
case 2: IA=0;IB=1;IC=0;ID=0;IEN=0;break;
case 3: IA=1;IB=1;IC=0;ID=0;IEN=0;break;
case 4: IA=0;IB=0;IC=1;ID=0;IEN=0;break;
case 5: IA=1;IB=0;IC=1;ID=0;IEN=0;break;
case 6: IA=0;IB=1;IC=1;ID=0;IEN=0;break;
case 7: IA=1;IB=1;IC=1;ID=0;IEN=0;break;
case 8: IA=0;IB=0;IC=0;ID=1;IEN=0;break;
case 9: IA=1;IB=0;IC=0;ID=1;IEN=0;break;
case 10: IA=0;IB=1;IC=0;ID=1;IEN=0;break;
case 11: IA=1;IB=1;IC=0;ID=1;IEN=0;break;
case 12: IA=0;IB=0;IC=1;ID=1;IEN=0;break;
case 13: IA=1;IB=0;IC=1;ID=1;IEN=0;break;
case 14: IA=0;IB=1;IC=1;ID=1;IEN=0;break;
case 15: IA=1;IB=1;IC=1;ID=1;IEN=0;break;
case 16: IA=0;IB=0;IC=0;ID=0;IEN=1;break;
case 17: IA=1;IB=0;IC=0;ID=0;IEN=1;break;
case 18: IA=0;IB=1;IC=0;ID=0;IEN=1;break;
case 19: IA=1;IB=1;IC=0;ID=0;IEN=1;break;
case 20: IA=0;IB=0;IC=1;ID=0;IEN=1;break;
case 21: IA=1;IB=0;IC=1;ID=0;IEN=1;break;
case 22: IA=0;IB=1;IC=1;ID=0;IEN=1;break;
case 23: IA=1;IB=1;IC=1;ID=0;IEN=1;break;
case 24: IA=0;IB=0;IC=0;ID=1;IEN=1;break;
case 25: IA=1;IB=0;IC=0;ID=1;IEN=1;break;
case 26: IA=0;IB=1;IC=0;ID=1;IEN=1;break;
case 27: IA=1;IB=1;IC=0;ID=1;IEN=1;break;
case 28: IA=0;IB=0;IC=1;ID=1;IEN=1;break;
case 29: IA=1;IB=0;IC=1;ID=1;IEN=1;break;
case 30: IA=0;IB=1;IC=1;ID=1;IEN=1;break;
case 31: IA=1;IB=1;IC=1;ID=1;IEN=1;break;
default:break;
}
PWMB_ENO = 0x40; //开显示
}
void SPI_Isr() interrupt 9
{
SPSTAT = 0xc0; //清中断标志
if (SPI_Cnt < 4096)
{
if(spi_frame) //切换缓存
{
SpiBuff2[SPI_Cnt] = SPDAT;
SPI_Cnt++;
}
else
{
SpiBuff1[SPI_Cnt] = SPDAT;
SPI_Cnt++;
}
}
if (SPI_Cnt >= 4096)
{
SPI_Cnt = 0;
spi_frame = !spi_frame; // 一帧接收完毕,切换缓冲
}
}
void SPI_init(void)
{
SPI_SS = 1;
SPCTL = 0x64; //使能 SPI 从机模式进行待机,传输期间SS引脚一直为低
// P_SW1 |= 0x00; // P3.5 P3.4 P3.3 P3.2
IE2 = ESPI; //使能 SPI 中断
SPSTAT = 0xc0; //清中断标志
SPI_Cnt = 0; //计数标志
spi_frame = 0; //缓存转换标志
}
//显示函数
void display()
{
bit frame;
u8 r, i;
u16 j;
EA = 0;
frame = spi_frame; // 锁定当前要显示缓存
LED1 = frame;
EA = 1;
if(frame)
{
for(r = 0; r < 32; r++)
{
scan(r); // 换行
j = r * 128; // 每行开始前,j定位到该行的第一个字节
for(i = 0; i < 128; i++)
{
P2 = SpiBuff1[j]; // 取出一个字节 (P2.0~P2.5 对应6根数据线)
j++;
CLK = 1;
CLK = 0;
}
LE = 1;
LE = 0;
}
}
else //切换到另一个缓存
{
for(r = 0; r < 32; r++)
{
scan(r); // 换行
j = r * 128;
for(i = 0; i < 128; i++)
{
P2 = SpiBuff2[j];
j++;
CLK = 1;
CLK = 0;
}
LE = 1;
LE = 0;
}
}
}
void PWM8_Init(void)
{
PWMB_PSCRH = 0x00;
PWMB_PS = 0x40; //使用P3.4 pwm8
PWMB_CCER2 = 0x00;
PWMB_CCMR4 = 0x60;
PWMB_CCER2 = 0x10;
PWMB_ARR = 2601;
PWMB_CCR8 = 2550;
PWMB_ENO = 0x40;
PWMB_BKR = 0x80;
PWMB_CR1 = 0x01;
}
void ADC_Init(void)
{
ADCTIM = 0x3f; //设置 ADC 内部时序
ADCCFG = 0x20; //设置 ADC 时钟为系统时钟/2/1
ADC_CONTR = 0x80; //使能 ADC
}
// 启动一次通道 10(光敏) 的 AD 转换
int ADCRead()
{
ADC_CONTR |= 0x40; //启动 AD 转换
_nop_();
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & 0x20)); //查询 ADC 完成标志
ADC_CONTR &= ~0x20; //清完成标志
return (ADC_RES << 8) | ADC_RESL; //读取 ADC 结果
}
void main()
{
u8 count;
P_SW2 |= 0X80;
P0M0 = 0x00; P0M1 = 0x07; //p0.0高阻,ADC10
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0xff; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
P7M0 = 0x00; P7M1 = 0x00;
P2SR = 0xff; //转换速度最快
P1SR |= 0x38;
P5SR |= 0x10;
ADC_Init();
PWM8_Init();
SPI_init();
EA=1;
while(1)
{
count++;
if(count > 32) //不想频繁转换亮度,随便多少都可以
{
count = 0;
ADC_CONTR = 0x80|10; //通道10
ADC_temp = ADCRead(); //进行亮度AD转换
if(ADC_temp<3300)PWMB_CCR8 = 2450; //最亮
if(ADC_temp>=3330 && ADC_temp<3360)PWMB_CCR8 = 2465;
if(ADC_temp>=3360 && ADC_temp<3390)PWMB_CCR8 = 2480;
if(ADC_temp>=3390 && ADC_temp<3420)PWMB_CCR8 = 2495;
if(ADC_temp>=3420 && ADC_temp<3450)PWMB_CCR8 = 2510;
if(ADC_temp>=3450 && ADC_temp<3480)PWMB_CCR8 = 2525;
if(ADC_temp>=3480 && ADC_temp<3510)PWMB_CCR8 = 2540;
if(ADC_temp>=3510 && ADC_temp<3540)PWMB_CCR8 = 2555;
if(ADC_temp>=3540 && ADC_temp<3570)PWMB_CCR8 = 2570;
if(ADC_temp>=3570 && ADC_temp<3590)PWMB_CCR8 = 2585;
if(ADC_temp>=3590)PWMB_CCR8 = 2599; //最暗
}
display();
}
} |
|