⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 5_5_3.c

📁 用C语言写的用于微新公司数字信号控制器30F6014的
💻 C
字号:
//6.5.3  程序清单
/************************************************************************
*	 程序说明:
*	
*  该程序配置UART1端口的波特率为9600,并用ADC从RP1,RP2和RP3
*  可调电位器读数,读取的数据通过串口传送去显示。
*
*  按键SW1按下时,读到的电位值开始传送;按键SW2按下时,数据传送结束。
*
************************************************************************/
#define __dsPIC30F6014__
#include <uart.h>
#include <adc12.h>
#include <p30F6014.h>

// 配置位
_FOSC(CSW_FSCM_OFF & XT_PLL4);  //XT 为4xPLL 振荡器, 失效保险时钟关闭
_FWDT(WDT_OFF);                   //禁止看门狗定时器
_FBORPOR(PBOR_OFF & MCLR_EN);  //禁止掉电复位,使能MCLR复位
_FGS(CODE_PROT_OFF);             //禁止代码保护


#define BAUDRATE 9600		  //所需的波特率
#define FCY  7372800			  // XTAL = 7.3728Mhz; 4 x PLL
#define SW1	!PORTAbits.RA12
#define SW2	!PORTAbits.RA13
#define LF	0x0A
#define CR	0x0D
#define NULL 0x00
#define WRITE_CHAR	0xA8
#define HOME_CLEAR	0x82
#define CURSOR_ON	0x8C

unsigned char RxValue;

void LCD_Display_Setup(void);
void LCD_Display_ClrCol(unsigned char x);
void LCD_Display_Pixel(unsigned char x,unsigned char y);
void LCD_Display_Byte(unsigned char value);
void LCD_Display_array(int *array_ptr[]);

//UART1 TX中断服务程序
void __attribute__((__interrupt__)) _U1TXInterrupt(void)
{
	IFS0bits.U1TXIF = 0;	//清中断标志位
}

//UART1 RX中断服务程序
void __attribute__((__interrupt__)) _U1RXInterrupt(void)
{
	IFS0bits.U1RXIF = 0;	         //清中断标志位
	RxValue = (char)U1RXREG;	    //从接收寄存器读值
	LCD_Display_Byte(WRITE_CHAR);	//在LCD上显示字符
	LCD_Display_Byte(RxValue);		//在LCD上显示接收到的值
}

void InitADC12(void);
void LoadADC(unsigned int offset);
void InitUART1(void);
void AverageADC(void);
void InitTMR3(void);

unsigned int RPValue[] = {1,2,3};


char ADCdata[] = {'R','P','1',SPACE,'=',SPACE,'1','2','3',CR,LF,
				       'R','P','2',SPACE,'=',SPACE,'1','2','3',CR,LF,
				       'R','P','3',SPACE,'=',SPACE,'1','2','3',CR,LF,	
								                      SPACE,CR,LF,NULL};

//主程序
int main(void)
{
unsigned char TxIndex;
unsigned char i;

	InitTMR3();	           //初始化TIMER3
	InitADC12();           //初始化ADC
	LCD_Display_Setup(); //初始化LCD显示
	LCD_Display_Byte(HOME_CLEAR);	//清LCD并把光标放到起始处
	LCD_Display_Byte(CURSOR_ON);    //开光标
	T3CONbits.TON = 1;                //打开定时器Timer3
	InitUART1();                       //初始化UART1
	while(1)			
	{
		TxIndex = 0;		
		while (!IFS0bits.ADIF); 	//转换完成?
		IFS0bits.ADIF = 0;			//清标志位
		AverageADC(); 			     //转换完成,从缓冲获取数据
		for (i = 0; i<=2; i++)
			LoadADC(i);			     //把数值放到缓冲
		while (ADCdata[TxIndex])	//传送数据
		{
			WriteUART1((int)ADCdata[TxIndex++]);
			while(BusyUART1());
		}
	}	
}

//Timer3初始化程序,使 Timer3 每10 mS发生一次
void InitTMR3(void)
{
	T3CON = 0x0010;			//内部时钟Tcy/8
	TMR3 = 0;
	PR3 = 0x2400;			//10mS时间到数值
}
	
//初始化ADC
void InitADC12(void)
{
 ADPCFG = 0xFF8F;				//所有的端口B都是数字I/O,RB6-RB4是模拟I/O
 ADCON1 = 0x0044;				//采用TMR3每10mSec自动转换									      
 ADCON2 = 0x042C;				//扫描输入,每12个采样中断一次
 ADCSSL = 0x0070;				//在引脚AN6, AN5和AN4扫描输入
 ADCON3 = 0x0000F;			    //TMR3 = 10ms , Tad = 8Tcy = 1uS
 ADCON1bits.ADON = 1;			// turn ADC ON
}

//取ADC信号的平均值
void AverageADC(void)
{
	RPValue[0] = ADCBUF2 + ADCBUF5 + ADCBUF8 + ADCBUFB;
	RPValue[0] = RPValue[0] >> 2;
	RPValue[1] = ADCBUF0 + ADCBUF3 + ADCBUF6 + ADCBUF9;
	RPValue[1] = RPValue[1] >> 2;
	RPValue[2] = ADCBUF1 + ADCBUF4 + ADCBUF7 + ADCBUFA;
	RPValue[2] = RPValue[2] >> 2;
}

//把ADC的值放入缓冲
void LoadADC(unsigned int offset)
{
unsigned char ADCbcd;
unsigned int j;

	j = offset;
	offset = offset*11 + 6;
	while(BusyUART1());					//等待传送完毕
	ADCbcd = (char)(RPValue[j] >> 8);	//转换ADC的值
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else ADCbcd = ADCbcd + 0x30;
	ADCdata[offset] = ADCbcd;
	ADCbcd = (char)(RPValue[j] >> 4);
	ADCbcd = ADCbcd & 0x0F;
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else ADCbcd = ADCbcd + 0x30;
	ADCdata[offset+1] = ADCbcd;
	ADCbcd = (char)RPValue[j] & 0x0F;
	if (ADCbcd > 9)
		ADCbcd = ADCbcd + 0x37;
	else 
ADCbcd = ADCbcd + 0x30;
	ADCdata[offset+2] = ADCbcd;

}
//初始化UART1
void InitUART1(void)
{
unsigned int baudvalue;
unsigned int U1MODEvalue;
unsigned int U1STAvalue;

	CloseUART1();
	ConfigIntUART1(UART_RX_INT_EN & UART_RX_INT_PR6 & 
						UART_TX_INT_DIS & UART_TX_INT_PR2);
	U1MODEvalue = 	UART_EN & UART_IDLE_CON &
						UART_DIS_WAKE & UART_EN_LOOPBACK &
						UART_EN_ABAUD & UART_NO_PAR_8BIT &
						UART_1STOPBIT;
	U1STAvalue =	UART_INT_TX_BUF_EMPTY &
						UART_TX_PIN_NORMAL &
						UART_TX_ENABLE & UART_INT_RX_CHAR &
						UART_ADR_DETECT_DIS &
						UART_RX_OVERRUN_CLEAR;
	baudvalue = ((FCY/16)/BAUDRATE) - 1;
	OpenUART1(U1MODEvalue, U1STAvalue, baudvalue);
}

//初始化SPI口,与LCD显示器通讯
void LCD_Display_Setup(void){
		LATGbits.LATG9 = 1; 	  //设SPI从引脚为高
		TRISGbits.TRISG9 = 0;	  //设SPI引脚为输出
		SPI2CON = 0x003c;	      //主模式, Clk = Fosc/64, 输入采样数据在输出时间中
								  //部,上升沿触发,时钟空闲为低
		SPI2STAT = 0x8000; 	      //使能SPI端口
}

//LCD清像素
void LCD_Display_ClrCol(unsigned char x){
		unsigned char counter;
		counter = 32;					// 清像素点32次
		while(counter > 0){
		LCD_Display_Byte(0xd9);		     //清像素,发送命令
		LCD_Display_Byte(x);	 	  	//确定像素X位置,发送命令
		LCD_Display_Byte(counter--); 	//上一个像位置,发送命令
		}
}

//LCD显示像素
void LCD_Display_Pixel(unsigned char x,unsigned char y){
		LCD_Display_Byte(0xd8);	     //设像素,发送命令
		LCD_Display_Byte(x);		// 确定像素X位置,发送命令
		LCD_Display_Byte(y);		// 确定像素Y位置,发送命令
}

//显示字节
void LCD_Display_Byte(unsigned char value){
		unsigned int junk;
		LATGbits.LATG9 = 1;		// 设从选择为高
		LATGbits.LATG9 = 0;		// 设从选择为低
		junk = SPI2BUF;			// 读缓冲避免溢出
		SPI2BUF = value;		       // 写数据到输出缓冲
		while(!SPI2STATbits.SPIRBF); // 检查传送是否完毕
}

//LCD显示阵列
void LCD_Display_array(int *array_ptr[]){
	unsigned char j,k;
	for (k=0; k<122; k++)
   	{
   		j = (unsigned char)array_ptr[k]/8;
		LCD_Display_ClrCol(k);				// 清除下一整列
      	LCD_Display_Pixel(k,j);		    // 设置像素位置
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -