2016-10-07 20:30:53 weirdosick 阅读数 325
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2489 人正在学习 去看看 朱有鹏
#include<reg52.h>
#include"delay.h"

#define PORT P0

unsigned char segdata[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char bitdata[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char tempdata[8];
unsigned char ch[9] = {0};
unsigned char flag = 0;

unsigned char hour = 20;
unsigned char min = 39;
unsigned char sec = 45;

sbit bit_select = P2^0;
sbit seg_select = P2^1;

void display()
{
        static unsigned char i = 0;

        PORT = 0xff;
        bit_select = 1;
        bit_select = 0;

        PORT = 0x0;
        seg_select = 1;
        seg_select = 0;

        PORT = tempdata[i];
        seg_select = 1;
        seg_select = 0;

        PORT = bitdata[i];
        bit_select = 1;
        bit_select = 0;

        i++;
        if(8 == i)
        {
            i = 0;
        }

}


void time0_init(void)
{
        EA = 1;
        TMOD |= 0x01;
        TH0 = (65536 - 20000) / 256;
        TL0 = (65536 - 20000) % 256;
        ET0 = 1;
        TR0 = 1;

}

void time0_isr() interrupt 1
{
        static unsigned char j = 0;

        TH0 = (65536 - 20000) / 256;
        TL0 = (65536 - 20000) % 256;

        j++;

        if(50 == j)
        {
            j = 0;
            sec++;

            if(60 == sec)
            {
                sec = 0;
                min++;

                if(60 == min)
                {
                    min = 0;
                    hour++;

                    if(24 == hour)
                    {
                        hour = 0;
                    }
                }
            }
        }   
            tempdata[0] = segdata[hour / 10];
            tempdata[1] = segdata[hour % 10];
            tempdata[2] = 0x40;
            tempdata[3] = segdata[min / 10];
            tempdata[4] = segdata[min % 10];
            tempdata[5] = 0x40;
            tempdata[6] = segdata[sec / 10];
            tempdata[7] = segdata[sec % 10];        

}

void uart_init(void)
{
    SCON = 0x50;
    TMOD |= 0x20;//Ò»¶¨ÒªÓÃÒì»ò
    TH1 = 0xfd;
    TR1 =1;
    EA = 1;
  ES = 1;
}

void uart_send_byte(unsigned char byte);
void uart_send_str(unsigned char *str);

//´®¿ÚÖжϺ¯Êý
void uart_isr() interrupt 4
{
      static unsigned char i = 0;
      if(RI)
        {
          ES = 0;
                ch[i] = SBUF;
                i++;
        if(8 == i)
                {   ch[i] = '\0';
                  i = 0;
                      flag = 1;
                }                   
                RI = 0;     
                ES = 1;
      }
}

//Êä³ö×Ö·û
void uart_send_byte(unsigned char byte)
{
      SBUF = byte;
      while(!TI);
      TI = 0;
}

//Êä³ö×Ö·û´®
void uart_send_str(unsigned char *s)
{
    while(*s != '\0')
    {
        uart_send_byte(*s);
        s++;
    }
}

void main()
{         

        time0_init();
        uart_init();
        while(1)
        {  
              if(flag)
                {
                    tempdata[0] = segdata[ch[0] - '0'];
                    tempdata[1] = segdata[ch[1] - '0'];
                    tempdata[2] = 0x40;
                    tempdata[3] = segdata[ch[3] - '0'];
                    tempdata[4] = segdata[ch[4] - '0'];
                    tempdata[5] = 0x3f;
                    tempdata[6] = segdata[ch[6] - '0'];
                    tempdata[7] = segdata[ch[7] - '0'];
                    hour = (ch[0] - '0') * 10 +(ch[1] - '0');
                    min = (ch[3] - '0') * 10 +(ch[4] - '0');
                    sec = (ch[6] - '0') * 10 +(ch[7] - '0');
                    uart_send_str(ch);
                    flag = 0;
                }
                display();  
        }
}
2019-03-10 23:09:23 Caoyang_He 阅读数 1074
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2489 人正在学习 去看看 朱有鹏

最近在完成一个物联网的作业,使用stc89c52作为主控芯片,完成一个智能远程交通灯的设计,其中大部分代码都是用的别人现成的,但是我发现要使用远程通信,就要使用串口,但是T0和T1已经被占用了。
好在使用的是52芯片,比51要多一个定时器。所以我在网上也是看了很多资料,许多都不能运行,我在进行部分修改后,终于在keli和proteus上实现了仿真测试。以下是我的代码和设计的电路。


               		       
/*-----------------------------------------------------------------------------
* 实 验 名		 : RS232串口试验
* 实验说明     : 单片机串口接收数据控制灯亮灭
* 连接方式     : 
* 注    意		 : 该试验使用的晶振是11.0592
*******************************************************************************/

#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int

uchar PuZh[36] = "hello world";

//--定义使用的IO--//

sbit LED=P2^0;


//--声明全局函数--//   
void UsartConfiguration();
void Delay_1ms(uint i);


/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无 * 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4
{
	uchar i;
  uchar receive_data;
	
  EA = 0;
	
  if(RI == 1) //当硬件接收到一个数据时,RI会置位
	{ 		
		RI = 0;
		receive_data = SBUF;//接收到的数据
			
		if(receive_data == '1')	 
		{
				LED =0;//接收到1亮灯
		}
		else
		{
				LED =1; //其他情况灯灭
		}
		
	}
		
		for(i=0; i<36; i++)
		{
			SBUF = PuZh[i];   //将要发送的数据放入到发送寄存器
			while(!TI);		    //等待发送数据完成
			TI=0;			        //清除发送完成标志位
			Delay_1ms(1);
		}
		EA = 1;
}

/*******************************************************************************
* 函 数 名       : main
* 函数功能		   : 主函数
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/

void main()
{

	UsartConfiguration();//初始化串口
	
	while(1);	
}
	
/*******************************************************************************
* 函 数 名       : UsartConfiguration()
* 函数功能		   : 设置串口
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/

void UsartConfiguration()
{	

	T2MOD = 0x01; 	//自动重载
	T2CON = 0x30; 	//T2用做发送接收时钟
	TH2 = 0xFF;  	//9600波特率,11.0592Mhz晶振
	TL2 = 0xDC; 
	RCAP2H = 0xFF; 
	RCAP2L = 0xDC; 
	SCON = 0x50; 	//串口方式1,1个起始位,1个停止位,8位数据,可变波特率
	PCON = 0X00;	//波特率不加倍
 	TR2 = 1;  		//启动T2 
	ES = 1;         //开串口中断
  	EA = 1;         //开总中断
}


/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms
* x * 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
  uchar x,j;
  
  for(j=0;j<i;j++)
    for(x=0;x<=148;x++);
}

由于不是用的自己电脑来画的图,所以就没有办法贴出图片,但是要是有空的话,我一定把图贴出来。但是我还说一下设计的大概思路,就是一个最小单片机系统RX端接compim的RX端,TX接compim的TX端,然后LED接P2口的0端。
在这里插入图片描述

2019-09-07 21:50:09 hishyboy 阅读数 476
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2489 人正在学习 去看看 朱有鹏

keilC碰到的问题

软件下载安装

1.一开始不知道keilC居然还有两个版本,下了个keil4和keil5都是ARM开发板的,结果研究了好一会儿才搞明白怎么用ARM版本编译,具体就是下载个C51的目录文件压缩包放到keilC目录下,然后修改下TOOLS.INI里面的内容
[C51]
PATH=“C:\Keil_v5\C51”
VERSION=5.26
BOOK0=HLP\Release_Notes.htm(“Release Notes”,GEN)
BOOK1=HLP\C51TOOLS.chm(“Complete User’s Guide Selection”,C)
TDRV0=BIN\MON51.DLL (“Keil Monitor-51 Driver”)
TDRV1=BIN\ISD51.DLL (“Keil ISD51 In-System Debugger”)
TDRV2=BIN\MON390.DLL (“MON390: Dallas Contiguous Mode”)
TDRV3=BIN\LPC2EMP.DLL (“LPC900 EPM Emulator/Programmer”)
TDRV4=BIN\UL2UPSD.DLL (“ST-uPSD ULINK Driver”)

TDRV5=BIN\UL2XC800.DLL (“Infineon XC800 ULINK Driver”)

TDRV6=BIN\MONADI.DLL (“ADI Monitor Driver”)
TDRV7=BIN\DAS2XC800.DLL (“Infineon DAS Client for XC800”)

TDRV8=BIN\UL2LPC9.DLL (“NXP LPC95x ULINK Driver”)
RTOS0=Dummy.DLL(“Dummy”)
RTOS1=RTXTINY.DLL (“RTX-51 Tiny”)

RTOS2=RTX51.DLL (“RTX-51 Full”)
TDRV9=BIN\STCMON51.DLL (“STC Monitor-51 Driver”)


目录和版本改成对应的就可以,不改估计也可以。
C51文件夹内容压缩包链接:
链接:https://pan.baidu.com/s/12BIvW8Q1P3sDf1b1mKGZbQ
提取码:eke9
2.至于keilC我自己随便下了个uvision5的用了,一般随压缩包都带pj补丁,具体操作各版本都一样
还有,到http://www.stcmcu.com网站下个最新版STC-ISP软件
在右上标签keil仿真设置里面添加型号和头文件到keilC中点击一下,按提示指定目录
在这里插入图片描述
然后就可以在keilC中创建工程的时候在下拉菜单找到STC的mcu
在这里插入图片描述

软件使用

碰到的问题主要是各种编译问题,一般都能解决,很多时候是打错字 中文输入法等引起
最恶心的是一个for循环语句不知怎么的后面居然有个分号,找了两个小时才找到错误在哪里,毕竟0经验

还有中文注释乱码问题,看图
在这里插入图片描述

开发板问题

开发板选择

建议选择和参考书配套的,便宜点就普中的,但是可能某些书上的例程需要修改下才能成功

驱动问题

一般开发板串口驱动,我的是USB转串口CH340/CH341
链接:https://pan.baidu.com/s/1XSqQTGbnuB1BypcwSy14cg
提取码:ejvw

其他

很多现在学51的应该和我差不多都是出于兴趣自学玩玩的,参考书推荐一个看起来轻松的《新概念51单片机C语言教程》,当然如果是想深入学习的,那自己另选吧,这本书只适合业余玩玩的,例子很简单,没有各种模块化编程,也没有状态机等等等等,甚至都没有汇编,但我觉得还是一本非常合适的参考书

PS:在写这些之前,我花了大概七八个晚上,每个晚上调试1-2个小时,就是想找出为什么舵机不能驱动,网上找了不下5个版本,每个版本都各种修改参数调试,各种软件模拟波形都是完美,就是一连上舵机就驱动不了,独立电源,上拉电阻,各种都试过,都没反应,今天晚上,我把pwm端口从P3^3换到P30,同时换独立电源,居然就成了,之前端口也换过,程序调试过N遍,独立电源也试过,就是没有同时换端口和独立电源,哪想到P33居然有问题,之前也测试过,我用延迟函数1秒切换电平用万用表量都没问题,就是pwm波形输出有问题,到现在都没明白为什么,太坑了

2016-10-08 21:24:24 weirdosick 阅读数 390
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2489 人正在学习 去看看 朱有鹏
#include <reg52.h>
#include "delay.h"



#define LCDPORT P0
sbit RS = P2^4;
sbit RW = P2^5;
sbit E = P2^6;

#define LCD_WRITE_DATA 1
#define LCD_WRITE_COM 0

unsigned char hour = 0;
unsigned char min = 0;
unsigned char sec = 0;
unsigned char ch[9];
unsigned char flag = 0;

unsigned char alarm_hour = 21;
unsigned char alarm_min = 8;
unsigned char alarm_sec = 21;

sbit beep = P2^7;


void alarm()
{ 

    if(alarm_hour == hour && alarm_min == min)
    { 
    beep = ~beep;  
    }
}


void timer0_init(void)
{
    EA = 1;
    TMOD |= 0x01;
    TH0 = (65536 - 20000) / 256;
    TL0 = (65536 - 20000) % 256;
    ET0 = 1;
    TR0 = 1;
}

void timer0_isr() interrupt 1
{
    static unsigned char j = 0;

    TH0 = (65536 - 20000) / 256;
    TL0 = (65536 - 20000) % 256;

    j++;

    if(50 == j)
    {
        j = 0;
        sec++;
        if(60 == sec)
        {
            sec = 0;
            min++;
            if(60 == min)
            {
                min = 0;
                hour++;
                if(24 == hour)
                {
                    hour = 0;
                }
            }
        }
    }
}

void lcd_write(unsigned char byte, unsigned char flag)
{
    if(flag)
    {
        RS = 1;
    }
    else
    {
        RS = 0;
    }
    RW = 0;
    E = 1;
    LCDPORT = byte;
    delay_us(5);
    E = 0;
}

void lcd_init()
{
    delay_ms(16);
    lcd_write(0x38, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x38, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x38, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x38, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x08, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x01, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x06, LCD_WRITE_COM);
    delay_ms(5);
    lcd_write(0x0C, LCD_WRITE_COM);
    delay_ms(5);
}


void dis_clock()
{
    lcd_write(0x80 + 4, LCD_WRITE_COM);
    lcd_write((hour / 10) + 0x30, LCD_WRITE_DATA);
    lcd_write((hour % 10) + 0x30, LCD_WRITE_DATA);
    lcd_write(':', LCD_WRITE_DATA);
    lcd_write((min / 10) + 0x30, LCD_WRITE_DATA);
    lcd_write((min % 10) + 0x30, LCD_WRITE_DATA);
    lcd_write(':', LCD_WRITE_DATA);
    lcd_write((sec / 10) + 0x30, LCD_WRITE_DATA);
    lcd_write((sec % 10) + 0x30, LCD_WRITE_DATA);
}

void uart_init(void)
{
    SCON = 0x50;
    TMOD |= 0x20;//Ò»¶¨ÒªÓÃÒì»ò
    TH1 = 0xfd;
    TR1 =1;
    EA = 1;
  ES = 1;
}

void uart_send_byte(unsigned char byte);
void uart_send_str(unsigned char *str);


void uart_isr() interrupt 4
{
      static unsigned char i = 0;
      if(RI)
        {
          ES = 0;
                ch[i] = SBUF;
                i++;
        if(8 == i)
                {   ch[i] = '\0';
                  i = 0;
                      flag = 1;
                }                   
                RI = 0;     
                ES = 1;
      }
}


void uart_send_byte(unsigned char byte)
{
      SBUF = byte;
      while(!TI);
      TI = 0;
}

//Êä³ö×Ö·û´®
void uart_send_str(unsigned char *s)
{
    while(*s != '\0')
    {
        uart_send_byte(*s);
        s++;
    }
}

void main()
{
    timer0_init();
    lcd_init();
    uart_init();
    while(1)
    {
        if(flag)
        {
            hour = (ch[0] - '0') * 10 +(ch[1] - '0');
            min = (ch[3] - '0') * 10 +(ch[4] - '0');
            sec = (ch[6] - '0') * 10 +(ch[7] - '0');
            uart_send_str(ch);
            flag = 0;
        }
        dis_clock();
        alarm();
    }
}
2016-09-20 21:32:40 newcong0123 阅读数 1352
  • 单片机有很多种-1.3.第1季第3部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第3个课程,主要讲了单片机的发展史,各种主流单片机的各自特点,STC51单片机的各系列的特点以及项目中如何选型主控单片机。

    2489 人正在学习 去看看 朱有鹏

main.c

#include "head.h"

code unsigned char timedata[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
code unsigned char bitdata[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char disdata[8];
unsigned char temp[7];

unsigned char sec = 0;
unsigned char min = 0;
unsigned char hour = 0;

unsigned char temp_buf[20];
unsigned char flag = 0;

void main()
{
	unsigned char i = 0;
	
    timer0_init();
	uart_init();
	
	while(1)
	{
	    display();
		manage();
			
	    ES = 1;                    //打开串口中断
		TR0 = 1;                   //打开定时器0,开始计数
		flag = 0;                  //标志位清0
	}
}


display.c

#include "head.h"

/*
======================
功能:修改时间显示值
======================
*/
void change_time()
{
    disdata[0] = timedata[hour / 10];
    disdata[1] = timedata[hour % 10];
	disdata[2] = 0x40;
	disdata[3] = timedata[min / 10];
    disdata[4] = timedata[min % 10];
	disdata[5] = 0x40;
	disdata[6] = timedata[sec / 10];
    disdata[7] = timedata[sec % 10]; 
}

/*
==========================
功能:动态扫描,显示数据
==========================
*/
void display()
{
    static unsigned char i = 0;
	
    TIMEPORT = 0x00;            //清空数据,防止重影
    seg_select = 1;
    seg_select = 0;

    TIMEPORT = 0xff;            //清空数据,防止重影
    bit_select = 1;
    bit_select = 0;

    TIMEPORT = disdata[i];      //取出显示值
    seg_select = 1;
    seg_select = 0;

    TIMEPORT = bitdata[i];      //取出位码
    bit_select = 1;
    bit_select = 0;	
	
	i++;
	if(8 == i)
	{
	    i = 0;
	}
}

uart.c

#include "head.h"

unsigned char buf[10];

/*
==================
功能:串口初始化
==================
*/
void uart_init()
{
    SCON = 0x50;    //设置串口的工作方式,8N1
	TMOD |= 0x20;   //设置定时器的工作方式,用作串口波特率
	TH1 = 0xfd;     //设置串口的波特率为9600
	TR1 = 1;
	EA = 1;
	ES = 1;
}

/*
============================
功能:串口中断服务函数
============================
*/
void uart_isr() interrupt 4
{
		static unsigned char i = 0;
		if(RI)
		{
			if(SBUF != ' ')
			{
				if(SBUF >= '0' && SBUF <= '9')
				{
					buf[i++] = SBUF;
				}
			}
			else
			{
					i = 0;
					flag = 1;
			}
			RI = 0;
		}
}

init.c

#include "head.h"

/*
===================
功能:初始化中断0
===================
*/
void timer0_init()
{
    EA = 1;
	TMOD |= 0x01;
	TH0 = (65536 - 20000) / 256;
	TL0 = (65536 - 20000) % 256;
	ET0 = 1;
	TR0 = 1;
}

/*
==========================
功能:中断0服务函数,计数
==========================
*/
void timer0_isr() interrupt 1
{
    static unsigned char i = 0;
	
	TH0 = (65536 - 20000) / 256;
	TL0 = (65536 - 20000) % 256;

    i++;
	
    if(50 == i)
	{
	    i = 0;
        sec++;

        if(60 == sec)
        {
	        sec = 0;
		    min++;
		
            if(60 == min)
		    {
		        min = 0;
			    hour++;
			
			    if(24 == hour)
			    {
			        hour = 0;
			    }
		    }
		}
	}
	
	change_time();    //修改显示时间
}

manage.c

#include "head.h"

unsigned char j = 0;

void manage()
{
	if(1 == flag)    //收到串口发送的信息
    {
	    TR0 = 0;     //关闭定时器0,即计数
	    ES = 0;      //关闭串口中断
	
		for(j = 0; j < 6; j++)    //将字符转换为整数
		{
			temp_buf[j] = buf[j] - '0';
		}
		
		/*如果小时的十位为2,则个位小于4,超过24小时置0*/
		if(temp_buf[0] == 2)      
		{
			if(temp_buf[1] < 4)
			{
				hour = temp_buf[0] * 10 + temp_buf[1];
			}
			else
			{
				hour = temp_buf[0] * 10;
			}
		}
		
		else if(temp_buf[0] < 2)    //小时十位小于2
		{
			hour = temp_buf[0] * 10 + temp_buf[1];
		}
		
		if(temp_buf[2] < 6)        //如果分钟十位小于6
		{
			min = temp_buf[2] * 10 + temp_buf[3];
		}
		else                       //否则将分钟第一位置0
		{
			min = temp_buf[3];
		}
		
		if(temp_buf[4] < 6)        //如果秒第一位小于6
		{
			sec = temp_buf[4] * 10 + temp_buf[5];
		}
		else                       //否则将秒的第一位置0
		{
			sec = temp_buf[5];
		}
	}
}

head.h

#ifndef _HEAD_H_
#define _HEAD_H_

#include <reg52.h>

#define TIMEPORT P0

sbit bit_select = P2^0;
sbit seg_select = P2^1;

extern code unsigned char timedata[10];
extern code unsigned char bitdata[8];
extern unsigned char disdata[8];
extern unsigned char temp[7];

extern unsigned char buf[10];
extern unsigned char temp_buf[20];
extern unsigned char flag;

extern unsigned char sec;
extern unsigned char min;
extern unsigned char hour;

extern void change_time();
extern void display();
extern void timer0_init();
extern void uart_init();
extern void manage();

#endif

单片机串口程序1

阅读数 557

单片机串口通信

阅读数 213

没有更多推荐了,返回首页