1.编程学习
- Char是单个字符的基本数据,也可以整形存储
- Char *是定义字符串;
Char,signed Char,unsigned Char的数据长度都是1字节,其输出可以用格式符%c(字符),%d(有符号10进制),%u(无符号10进制),如果值大于127的话就用unsigned Char(0-255),而unsigned int表示32位无符号。
1.1char定义:
Char c[10];
1.2char初始化:
C[0]=’1’;……
用字符常量逐个初始化数组
char c[ ]={‘c’,‘ ’,‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’};//数组长度为9
用字符串常量初始化数组
char c[ ]=“C program”;(这里是双引号)此时数组c的长度不是9,而是10。因为字符串常量的最后由系统加上一个’\0’。上面的初始化与下面的初始化等价。
char c[ ]={‘c’,‘ ’,‘p’,‘r’,‘o’,‘g’,‘r’,‘a’,‘m’,’\0’};
Unsigned char temp[2]={‘\0’}
1.3DSP的内置数据类型
1.4数据的移动
dat>>=1;//读到数据后右移一位
2.返回数组的自定义函数
关于数组,字符串结尾一定加’\0’;想在WIN下显示换行;\r’,’\n’
法1.一个函数想返回很多值,你就把值放在字符数组中
#include<…>
Unsigned char temp[2]={‘\0’};//这就是存放返回值的数组
//定义子函数
Void read_temp()
{
Unsigned char templow;//8bit
Unsigned char temphigh;
Unsigned char tempflag=0;
Unsigned char disposeValue;
Templow=readdata();//读到第一个字节
Temphigh=readdata();//读到第二个字节
disposeValue=(temphigh<<4 | templow>>4);取位,可以看出unsigned char是8位
if(disposeValue>=128)//大于128说明是-数,因为unsigned char
{
disposeValue=~disposeValue+1;//取反再加1,补码变原码
tempFlag=1;
}
Temp[0] = disposeValue;//这样就把参数传出去了
Temp[1] = templow & 0x0f;
}
法2.把传回的数组放在输入中
//l是table_u的大小table_u是输入的数组(unsigned),table_i是输出的数组(signed)
Void u8_int (char l,Uint8 *table_u,int *table_i)
{
Uint8 t;
Char i;
For(i=0;i<l;,i++)
{
If(table_u[i]>127) //还是判断正负数
{
t = ~table_u[i]+1;
Table_i[i]=-(int)t;//强制变为int,负的
}else
Table_i[i]=table_u[i];//传出到输出数组中
}
}
法3.定义全局变量
ds18b20.h
extern char table[9];
///
ds18b20.c
#include "ds18b20.h"
char table[9];
void int_char(int a)
{
int tt1;
tt1=a;
table[0]=tt1/10000+0x30; //百位
table[1]=tt1%10000/1000+0x30;//十位
table[2]=tt1%1000/100+0x30;//个位
table[3]='.';
table[4]=tt1%100/10+0x30;//个位;
table[5]=tt1%10+0x30;//十分位;
table[6]='\r';//r回车n换行0结束
table[7]='\n';//换行
table[8]='\0';//表明字符串的结束
}
//
main_ds18b20.c
int_char(tt1);
3. 指令
主机写指令:低位在前,高位在后;
ds18b20发送:先发低位,再发高位。
3.1干预DSP的GPIO
每个IO都有一个数据寄存器,当IO配置为输出时,相GPxDAT中写数据就可以决定输出状态;
GPxDAT.bit.xx=0,输出变低;
GPxDAT.xx=1,输出变高
当IO配置为输入时,读取GPxDAT中的数据就可以决定输入状态;
4. ds18b20
这里就说明了ds18b20传出的数据要乘分度。因为最低四位是小数,也就是1111表示1度,用1/16=0.0625
它的温度寄存器格式,高5位为符号位。图中写法为+125;若温度为负,10位数值用补码表示。
关于它的使用(通信):
每次都是
- 初始化
- ROM指令
- DS18B20功能指令
4.1复位与存在脉冲
4.2读写
4.3主机写的逻辑0与逻辑1规定
4.4DS18B20的逻辑0与逻辑1规定
5.编程
ds18b20.h
函数的声明
#ifndef APP_DS18B20_DS18B20_H_
#define APP_DS18B20_DS18B20_H_
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
extern char table[9];//全局变量的声明,用于存放Uart发的字符串
#define uchar unsigned char
#define DQ_DIR GpioCtrlRegs.GPBDIR.bit.GPIO40 //方向
#define DQ GpioDataRegs.GPBDAT.bit.GPIO40//数值
uchar Init_DS18B20();
uchar ReadOneChar(void);
void WriteOneChar(uchar dat);
float ReadTemperature();
void int_char(int a);
#endif /* APP_DS18B20_DS18B20_H_ */
ds18b20.c
函数的定义
#include "ds18b20.h"
char table[9];//说明全局变量
/*************************************************/
/* DS18B20的初始化 */
/*************************************************/
uchar Init_DS18B20()
{
Uint16 i;
i=0;
EALLOW;
DQ_DIR=1; //设置为输出状态
EDIS;
DQ=0; //拉低电平
DELAY_US(650);//延迟650us
DQ=1; //释放总线
DELAY_US(15);//延迟15us
EALLOW;
DQ_DIR=0; //设置为输入状态
EDIS;
while (DQ) //再等15-60us的响应时间
{
DELAY_US(1);
i++;
}
if(i>60)
return 0;
else
i=0;
while(!DQ) //在接收ds18b20的低电平
{
DELAY_US(1);
i++;
}
if(240>i>60)
{i=0;
return 1;//成功
}
else
return 0;//失败
}
/*************************************************/
/* 读字节子函数 */
/*************************************************/
uchar ReadOneChar(void)
{
uchar i=0,dat=0;
for (i=8;i>0;i--)
{
EALLOW;
DQ_DIR=1; //设置为输出状态
EDIS;
DQ=0;
DELAY_US(5);//延迟5us
DQ=1;
DELAY_US(6);//延迟6us,等待数据稳定
dat>>=1;//读到数据后右移一位
EALLOW;
DQ_DIR=0; //设置为输入状态
EDIS;
if(DQ)
dat|=0x80;//如果收到1,dat的最高位置1,因为右移
DELAY_US(60);//延迟60us
}
return dat;
}
/*************************************************/
/* 写字节子函数 */
/*************************************************/
void WriteOneChar(uchar dat)
{
uchar i;
for(i=8;i>0;i--)
{
EALLOW;
DQ_DIR=1; //设置为输出状态
EDIS;
DQ=0;
DELAY_US(5);//延迟5us
DQ=dat & 0x01;//取了dat的最低位,从低位开始发bit,如果dat是0就发0;是1就发1
DELAY_US(68);//延迟68us
DQ=1;
DELAY_US(5);//延迟5us
dat >>=1;
}
}
//读取温度
float ReadTemperature()
{
uchar a=0;
uchar b=0;
float t=0;
uchar temp;
//每次操作都是三步骤,这次为了启动温度转换
Init_DS18B20();
DELAY_US(1000);//延迟1ms
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
//这次是读数据
Init_DS18B20();
DELAY_US(1000);//延迟1ms
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0xbe); //跳过读序号列号的操作
a=ReadOneChar();//低字节(因为ds18b20先发LSB,raedonechar只读8个bit,所以a是低字节,b是高字节)
b=ReadOneChar();//高字节
//这里ds18b20还在发送,但不收
//判断温度的正负
if((b&0x80) == 1)
{
b=b&0x07;
b=~b+1;//取补码
}
temp=(b<<4|a>>4);
t=temp*1.0+0.0625*(a&0x0f);//小数乘0.0625,原因是1111才表示1度,1/16=0.0625
return(t);
}
//输入TT1整数
void int_char(int a)
{
int tt1;
tt1=a;
table[0]=tt1/10000+0x30; //百位
table[1]=tt1%10000/1000+0x30;//十位
table[2]=tt1%1000/100+0x30;//个位
table[3]='.';
table[4]=tt1%100/10+0x30;//个位;
table[5]=tt1%10+0x30;//十分位;
table[6]='\r';//r回车n换行0结束
table[7]='\n';//换行
table[8]='\0';//表明字符串的结束
}
main_ds18b20.c
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x 例子相关头文件
#include "ds18b20.h"
#include "time.h"
#include "uart.h"
#include "leds.h"
#define uchar unsigned char
void init_port(void);
void main(void)
{
float tt;
int tt1,tt2;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(9600);
init_port();//初始化gpio口
while(1)
{
tt=ReadTemperature();
tt1=tt*100+0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
int_char(tt1);
if(abs(tt2-tt1)>0.2)
{
UARTa_SendString(table);
}tt2=tt1;
}
}
void init_port(void)
{
EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0; // 使能GPIO10 引脚内部上拉
GpioCtrlRegs.GPBMUX1.bit.GPIO40 =0; // 配置GPIO10为通用I/O口
GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0; // GPIO40与系统时钟SYSCLKOUT 同步
EDIS;
}
6.Matlab实时绘图
main.c
clear all;
delete(instrfindall)
clear obj1
global obj1;
global data;
global sendbuff;
global data1;
global data2;
global data3;
global data4;
global data5;
global dian_ya;%图中的y轴变量
global x;%用于画图
x=0;
dian_ya=0;
data1=0;
data2=0;
data3=0;
data4=0;
data5=0;
global n;
n=0;
data = zeros(5,1);
sendbuff = zeros(1,8);
obj1 = serial('com8');
fclose(obj1);
set(obj1, 'InputBufferSize', 100);
set(obj1, 'OutputBufferSize', 100);
set(obj1, 'BaudRate', 9600);
set(obj1, 'Timeout', 15.0);
set(obj1,'BytesAvailableFcnMode','terminator');
set(obj1,'terminator',10);
set(obj1,'BytesAvailableFcn',@my_callback1);
fopen(obj1);
function my_callback1(obj1,event)
global data;
global data1;
global data2;
global data3;
global data4;
global data5;
global dian_ya;
global x;
data = fread(obj1 , 9);%取决于发送的数组大小,真实的个数(1,9)
if length(data)==9
if data(4)=='.'
data1=data(1)-48;%减48就是去掉0x30;
data2=data(2)-48;
data3=data(3)-48;
data4=data(5)-48;
data5=data(6)-48;
dian_ya=100*data1+10*data2+data3+0.1*data4+0.01*data5;
end
end
disp(dian_ya);
x = [x dian_ya];
plot(x);
axis([0 inf 27 31]);
title('From Dsp');
xlabel('Sample');
ylabel('温度(C°)');
drawnow;
end