When I first looked at ADC, I was confused. Later, I looked through the chip manual and found it very detailed and helpful.
Read more chip manuals!
/* Function: Use the internal AD of 12C5A60S2 to read the external three-way voltage and display it on 1602*/
/* Up to 8 voltages can be input simultaneously, set P1ASF */
#include <STC12C5A.H>
#include
sbit RS = P2^6; //Define the port used by 1602
sbit RW = P2^5;
sbit EN = P2^7;
#define uchar unsigned char;
#define uint unsigned int;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0 //Connect to 1602 data port P0
//uchar b,i,ge,shi,bai;
uchar da1=0,da2=0,da3=0;
double Data,c;
char a[5]="";
fly ADC_Chanul_Turn=0;
/*------------------------------------------------
uS delay function, with input parameter unsigned char t, no return value
unsigned char is used to define an unsigned character variable, whose value range is
0~255 Here we use a 12M crystal oscillator. Please use assembly for accurate delay. Approximate delay
The length is as follows: T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS delay function, with input parameter unsigned char t, no return value
unsigned char is used to define an unsigned character variable, whose value range is
0~255 Here we use a 12M crystal oscillator. Please use assembly code for accurate delay.
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//About 1mS delay
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
Busy detection function
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
DataPort= 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
Write command function
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
while(LCD_Check_Busy()); //Wait if busy
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com; //
_nop_();
EN_CLR;
}
/*------------------------------------------------
Write data function
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
while(LCD_Check_Busy()); //Wait if busy
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
_nop_();
EN_CLR;
}
/*------------------------------------------------
Clear screen function
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
Write String Function
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)//y is the number of rows, x is the horizontal coordinate, and the last one is the character
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); // indicates the first line
}
else
{
LCD_Write_Com(0xC0 + x); // indicates the second line
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
Write character function
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
Initialization function
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*Display mode setting*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*Display off*/
LCD_Write_Com(0x01); /*Clear the screen*/
LCD_Write_Com(0x06); /*Display cursor movement settings*/
DelayMs(5);
LCD_Write_Com(0x0C); /*Display on and cursor setting*/
}
/*------------------------------------------------
ADC Function
------------------------------------------------*/
void InitADC() //initial AD register
{
P1ASF=0X07; //0xff sets all P1 ports as ADC channels, 0x07=0000,0111 means using P10, P11, P12 as input
ADC_RES=0X00; //Clear the high 8-bit buffer data
if(ADC_Chanul_Turn%3==0)//external reference voltage
{
ADC_CONTR=0xF0; //AD conversion control register, 1111, 0000 P10 port
_nop_();
_nop_();
_nop_();
_nop_();
ADC_CONTR=0xE8; //1110,1000 (clear Flag, set Start)
}
if(ADC_Chanul_Turn%3==1)
{
ADC_CONTR=0xF1; // 1111,0001 P11 port
_nop_();
_nop_();
_nop_();
_nop_();
ADC_CONTR=0xE9; //1110,1001
}
if(ADC_Chanul_Turn%3==2)
{
ADC_CONTR=0xF2; //1111,0010 P12 port
_nop_();
_nop_();
_nop_();
_nop_();
ADC_CONTR=0xEA; //1110,1010
}
}
void timer0() interrupt 1 //interrupt 1: timer 0, interrupt3: timer 3
{
TH0=(65536-20000)/256; //High eight bits (need to represent the timing of Xms, the counter counts from 65536-X to 65536, because it is 16 bits, it can only be divided into high and low bits)
TL0=(65536-20000)%256; //low eight bits
InitADC();
}
void adc_isr() interrupt 5 //The FLAG flag is set to trigger an interrupt. There is no priority setting, but timer 0 has a higher priority at the same priority level.
{
//V_5REF=V_1REF*256/da_ref;
if(ADC_Chanul_Turn%3==0) //External reference voltage
{
da1=ADC_RES; //Get conversion result
Data=((double)da1/256)*5; //Get eight bits to calculate the reference voltage Data,
c =Data;
}
if(ADC_Chanul_Turn%3==1)
{
da2=ADC_RES; //Get conversion result
Data=((double)da2/256)*5; //Get eight bits to calculate the actual value Data,
c =Data;
}
if(ADC_Chanul_Turn%3==2)
{
da3=ADC_RES; //Get conversion result
Data=((double)da3/256)*5; //Get eight bits to calculate the actual value Data,
c =Data;
}
a[0]=((int)c%10+0x30); //units (voltage < 5, only units) //0x30: represents "0" in ASCII code, must be converted into a character and stored in a character array before it can be displayed on the 1602 LCD screen
a[1]=0x2e; //decimal point
a[2]=((int)(c*10)%10+0x30); // tenth place
a[3]=((int)(c*100)%10+0x30);// Percentile
a[4]='\0'; // Add the end character to make it a string
if(ADC_Chanul_Turn%3==0) LCD_Write_String(0,0,a);
if(ADC_Chanul_Turn%3==1) LCD_Write_String(5,0,a);
if(ADC_Chanul_Turn%3==2) LCD_Write_String(0,1,a);
ADC_CONTR&=0xEF; // Flag clear
ADC_Chanul_Turn++;
if(ADC_Chanul_Turn==252)
ADC_Chanul_Turn=0;
}
void main()
{
LCD_Init();
LCD_Clear(); //Clearing
//LCD_Write_String(0,2,"Hello Dog!");
DelayMs(255);
TH0=(65536-20000)/256; //Start timer 0
TL0=(65536-20000)%256;
EA=1; //Open global interrupt
ET0=1; //Enable timer zero interrupt
EADC=1; //Enable ADC interrupt
TR0=1;
while(1);
}
Previous article:Is the 51 single-chip microcomputer a von Neumann or Harvard structure?
Next article:STC51 series MCU power-off-free download (hot start download)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- msp430g2553-minimum system
- [Qinheng RISC-V core CH582] Transplantation of RF code 01
- Control principle of ADC0832
- The pins of the components in the PADS self-made package library are missing
- Application of Keithley Source Meter in Electronic Thin Film Materials
- How to switch the unit of Proteus simulation software from inches to mm? Pressing m does not work, and Baidu can't find it
- Examples of capacitor applications in power supply design (recommended for collection)
- How can I hide certain items when printing in AD, such as the frequency mark of the crystal oscillator?
- gw1n FPGA reads ADS8598H actual DC measurement
- Shouldn't the charging curve of a capacitor be inversely proportional to its discharging curve?