历史上的今天
今天是:2025年01月14日(星期二)
2018年01月14日 | PDIUSBD12 USB 驱动程序
2018-01-14 来源:eefocus
一.实验目的
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 个信号量,其含义如下:
上一篇:LED16*16点阵滚动显示程序
下一篇:1602液晶电子时钟程序
史海拾趣
|
习惯于keil 的环境,也刚学了点stm32,觉得stm32 的固件库用起很方便的,在LPCXpresso 上师兄些都讲得过多,也过细,我想“另类”一点,写一篇keil 的文章Lpc 没有提供有固件库,但看它的例子,想了一下,何不将例子中的文件做成固件库呢? ...… 查看全部问答> |
|
金丝的焊接对LED的品质起着决定性的作用,金丝的粗细就决定了他的焊接,在电及和支架上所能承受的拉力和推力,比如说08的金丝它焊接在支架上只能承受3到5克左右的拉力不断,09的金丝就能承受6到8克的拉力不断,10的就更好了。还有就是金丝也是做LED ...… 查看全部问答> |
|
求Compact c# 如何使Contextmenu的字体变大和加图标 在compact 2005 c#下开发 1,如何能够改变字体大小(原来字太小,想大点,找不到地方设置) 2,能不能加图片呢(好像照目前的东西看,是不行)… 查看全部问答> |
|
在eboot中增加显示logo的功能,在OemInit 函数之后有一段时间LCD不显示,为何? 我用的PXA270,在OemInit 函数之前都能显示, 但在OemInit 函数之后有一段时间LCD不显示, 是不是lcd在那个地方被关掉了? 因为我发现lcd的P CLOCK没有了, … 查看全部问答> |
|
采集程序在运行了之后会出现一个错误,the specified group is in use,用探针看,除了循环的第一次error实现the operation could not compelte with limit time外,第二次以后的循环在config处error就开始输出这个错误,这是什么原因啊?而且,这 ...… 查看全部问答> |




