PDIUSBD12 USB 驱动程序演示实验

pdiusbd12 usb 驱动程序演示实验
一.实验目的
pdiusbd12(简称d12) usb 芯片符合usb1.1 协议,广泛应用于各种的usb 设备。
本实验程序展示了如何在small rtos51 操作系统中实现d12 驱动程序的编写。
示例主要实现了如下功能:usb 设备的枚举,通过d12 的端点2 接受来自上位机的数
据,并通过单片机的串口转发回上位机,同时驱动zlg7290 显示0~9 的数字。
二.实验设备及器件
pc 机 一台
dp-51proc 单片机综合仿真实验仪 一台
usb d12 park 模块 一台
usb 连接线 一根
三.实验步骤
1. d12 park 插到a6 区的排针内;
2. 使用导线把a2 区的int1 与a6 区的p1_int0 相连;
3. 使用导线把a2 区的t0 与a6 区的p1_io2 相连;
4. 使用导线把a2 区的t1 与a6 区的p1_io5 相连;
5. 使用导线把a2 区的a15 与a6 区的p1_cs 1 相连;
6. 使用导线把a2 区的p16、p17 分别与d5 区的scl、sda 相连;
7. 使用导线把a2 区的p10 与d5 区的/rst 相连,并短接d5 区的jp1;
8. 使用导线连接a2 区的p14 与b10 区的zdj_a;
9. b10 区的zdj_b 连接到c1 的gnd;
10. 短接b10 区jp18 的电机电源跳线
四.实验参考程序主要部分
/**************************************************************
small rtos(51)
the real-time kernel(for keil c51)
(c) copyright 2002-2004, chenmingji
all rights reserved
v1.20
***************************************************************/
#include config.h
/**************************************************************
声明全局变量
**********************************************************/
extern eppflags beppflags; /*usb 事件标志*/
extern uint8 xdata genepbuf[]; /*信号包缓冲区(命令区)*/
extern uint8 xdata epbuf[]; /*信号包缓冲区(数据区)*/
extern uint16 data d12_data; /*d12 数据的地址变量*/
extern uint16 data d12_command; /*d12 命令的地址变量*/
//指针的null 为0,这个变量占用0 地质避免出现有效的null 指针
uint8 os_q_mem_sel notuse _at_ 0x0000;
uint8 xdata showcase[8];
uint8 xdata pwmh; //高电平脉冲的个数
uint8 xdata pwm; //pwm 周期
uint8 xdata counter;
uint8 key_buf[2];
void enumerate_task(void);
void usb_rec_task(void);
void change_speed_task(void);
void get_key_task(void);
void intt1() interrupt 3
{
counter++;
if(counter < pwmh)
{
p1_4 = 1; //p1.4 变为高电平
}
else
{
p1_4 = 0;
}
}
void usb_isr(void) interrupt 2
{
os_int_enter();
ex1 = 0;
ossemintpost(d12_isr);
osintexit();
}
/**********************************************************
**名称:init_port()
**功能:端口初始化,d12suspd 复位为0
****************************************************************/
void init_hard()
{
p0 = 0xff;
p1 = 0xff;
p2 = 0xff;
p3 = 0xff;
d12suspd = 0;
}
/**************************************************************
** 函数名称: init
** 功能描述: 初始化函数,一般在多任务环境启动前调用
**************************************************888**************/
void init(void)
{
tmod &= 0xf0;
tmod |= 0x01;
// 每10ms 发生一次t0 中断
tl0 = (65536 - (11059200 / 12) / 100) % 256;
th0 = (65536 - (11059200 / 12) / 100) / 256;
et0 = 1;
tr0 = 1;
pt0 = 0;
ea = 1;
}
void control_init(void)
{
pwmh=0x00;
counter=0x01;
pwm=255;
tmod = tmod & 0x0f;
tmod = tmod | 0x20; //定时器1 在模式2 下工作
tl1=0x00;
th1=0x00; //自动重装的值
tr1=1;
et1 = 1;
}
/**************************************************************
** 函数名称: void init_display(void)
** 功能描述: 初始化led 显示
*****************************************************************/
void init_display(void)
{
uint8 i;
zlg7290_rst = 0;
_nop_();
_nop_();
zlg7290_rst = 1;
for (i = 0; i < 8; i++)
{
showcase[i] = 31;
}
zlg7290_sendbuf(showcase,8);
}
void main(void)
{
osinit();
init_hard(); /*初始化硬件*/
init();
control_init();
it1 = 0;
ex1 = 1;
px1 = 1;
init_display();
d12_data = 0x7002; /*定义数据地址*/
d12_command = 0x7003; /*定义命令地址*/
d12_setdma(0x0); /*不使用dma 功能*/
beppflags.value = 0; /*初始化usb 寄存器*/
ostaskcreate(usb_rec_task , null , 0); //创建usb 中断处理任务
while(1)
{
pcon = pcon |0x01 ; /* cpu 进入休眠状态 */
}
}
/*************************************************************
** 函数名称: void enumerate(void)
** 功能描述: 完成usb 请求处理的任务
************************************************************/
void enumerate_task(void)
{
//创建其他优先级低的任务
ostaskcreate(get_key_task, null,2);
ostaskcreate(change_speed_task, null,3);
while(1)
{
oswait(k_tmo, 2);
it1 = 0;
ex1 = 1;
reconnect_usb();
while(usb_vin)
{
usbserve();
oswait(k_tmo, 1);
}
}
}
/*******************************************************
** 函数名称: void usb_rec(void)
** 功能描述: usb 中断处理任务
**************************************************************/
void usb_rec_task(void)
{
ossemcreate(d12_isr , 0);
ossemcreate(d12_use , 1);
ostaskcreate(enumerate_task , null ,1); //创建usb 请求处理任务
while(1)
{
ossempend(d12_isr , 0);
ossempend(d12_use , 0);
fn_usb_isr();
ossempost(d12_use);
ex1=1;
}
}
/*************************************************************
** 函数名称: void change_speed_task(void)
** 功能描述: 修改马达速度任务。
*************************************************************/
void change_speed_task(void)
{
while(1)
{
os_enter_critical();
if( beppflags.bits.ep1_rxdone)
{
pwmh = genepbuf[0];
beppflags.bits.ep1_rxdone = 0;
}
os_exit_critical();
showcase[0] = pwmh %10;
showcase[1] = (pwmh /10)%10;
showcase[2] = (pwmh /100)%10;
os_enter_critical();
zlg7290_sendbuf(showcase,8);
os_exit_critical();
oswait(k_tmo,9);
}
}
/***********************************************************
** 函数名称: void get_key_task(void)
** 功能描述: 获取按键值任务。
**************************************************************/
void get_key_task(void)
{
while(1)
{
os_enter_critical();
key_buf[0] = zlg7290_getkey();
os_exit_critical();
oswait(k_tmo, 1);
if(key_buf[0] == 0)
{
continue;
}
os_enter_critical();
key_buf[1] = zlg7290_getkey();
os_exit_critical();
if(key_buf[0] != key_buf[1])
{
os_enter_critical();
d12_writeendpoint(3, 1, &key_buf[0]);
os_exit_critical();
}
}
}
五.实验示例程序简析
本由于驱动程序中使用了usb51s.lib 库,故关于该库的使用方法详见实验仪配套光盘
中的《 pdiusbd12 固件编程指南 》和书《 pdiusbd12 固件编程与驱动开发 》。这里仅
仅就叙述如何在small rtos51 下编写d12 usb 驱动程序。
由于对pdiusbd12 的操作是一种不能重入的操作,所以必须要在这一次操作完成后才
能进行下一次对pdiusbd12 的操作。因此,对pdiusbd12 器件的操作采用了一个信号量
(d12_use)来管理。这种信号量管理的方法就像有很多个门共用一把钥匙,必须一次只能
开一个门,而开这个门的先后则由任务的优先级来决定。
在驱动中使用了2 个信号量,其含义如下:
􀁺 d12_use: 不为0,表示pdiusbd12 处于空闲状态,可以使用;为0,则表示
pdiusbd12 正在使用中。不允许其他任务对pdiusbd12 进行操作。此信号量在
创建时被初始化为1。
􀁺 d12_isr: 不为0,表示检测到pdiusbd12 产生的usb 中断请求;为0,表示
没有usb 中断请求或者usb 中断请求已被执行处理。,此信号量在创建时被初始
化为0。
控制马达转速的方法很多,pwm(脉宽调制)方式是比较常见的一种,实现较简单并
且效果好。在dp-51pro.net 中可以实现pwm 控制马达转速实验,其马达控制电路参见
综合实验7 电机实验.。
本例程中,pwm 波形由定时器1 的周期性中断产生。其代码实现见程序清单5.4。定
时器1 中断服务函数(intt1)对全局变量counter 进行自增计数,并与pwmh 进行比
较,根据比较结果控制p1_4(波形输出引脚)输出电平的高低,从实现pwm 的输出。马达的
转速与pwm 波形中的高电平之占空比成正比。
六.程序演示
由于本示例程序需要跟pc 机进行数据通讯,故必须与pc 机相关软件配合使用才能实
现所有的功能。上位机软件可以使用配套光盘中的usb 调试助手(1.2 版)(有关usb 调试助
手的使用请见其帮助文件),该软件用于向实验仪发送控制数据和接收发上来的按键值数据。
使用usb 调试助手软件之前还必须安装d12 驱动程序方可正常使用。
首先将usb_d12.hex 文件下载到实验仪中,运行单片机中的程序。单片机将配置
pdiusbd12 并进行usb 枚举,usb d12park 模块上的led 灯将闪烁几次。、两、三秒后,
若usb 枚举成功,模块上的led 将常亮,表示usb 连接正常。此时打开usb 调试助手,
选择名称为philips pdiusbd12 smart evaluation board 的设备,设置接收端点和发送端点都
为端点1,设置接收和发送管道大小为16 字节。按下启动按扭,这样便与实验仪建立的usb
连接。向发送区填入1 个字节的数据,然后发送到实验仪,这样便可实现马达的变速。按下
实验仪中d7 区的按键,在pc 上便可接收到该按键的键值。

儿童手表新标GB/T 41411—2022
小米11首发供不应求
抢攻物联网商机 必不可缺技术元素
通信业主要高层将隆重出席2010年 GSM 协会亚洲移动通信
智能家居中电池特性分析及设计方案分享
PDIUSBD12 USB 驱动程序演示实验
一种改进的DSP固定点采样算法
电机电阻如何检测好坏
是德科技将于2月23日举行USB4.0仿真测试专题研讨会
关于二极管15个经典问答不可不知
基于残差精炼的新模块提升图像超分辨性能
罗姆600V耐压超级结MOSFET R60xxVNx系列产品介绍
2018年上半年中国智能手机市场分析:销量下降10%,荣耀表现亮眼
处理器升级与功能融合,带来HMI设计更多可能
华为进行这些功率器件的研发,究竟是在下一盘怎么的大棋?
浪涌保护器和防雷器有何区别
在物联网中对云接口和软件需求
关于触控屏一体机红外与电容选择哪个更好
西门子plc的型号选择_西门子plc型号说明
孢子捕捉仪是什么,它的主要作用是什么