计组学习第四天 总线 2023.06.12

总线是计算机中数据传输的重要通道,分为片内总线、系统总线和IO总线等。系统总线包括数据、地址和控制总线,用于CPU、主存和设备间通信。总线性能由传输周期、时钟频率、宽度和带宽等指标衡量。常见结构有单总线、双总线和三总线结构,每种有其特定应用场景。

总线概述

总线定义

总线就是公共信息传送的线路
分时:同一时刻只允许一个设备在总线上传输数据,可以多个设备接收(不产生冲突就行)
共享:总线上挂着很多部件,部件之间都可以交换数据。

总线设备

按对总线有无控制功能分为主设备从设备
主设备:获得总线控制权的设备
从设备:只能响应总线命令。

总线的分类

功能划分

片内总线

芯片内部的总线,就比如CPU内部,寄存器之间或者寄存器和ALU之间就是片内总线。

系统总线

数据总线:传输数据用的,位数和存储字长或者机器字长一样
地址总线:传输地址用的,位数和主存地址空间的大小有关。
控制总线:传送控制指令。

IO总线

连接低速IO设备(对于总线来说IO算是很慢的啦),将低速总线和高速总线分离,增加数据同步和系统总线的性能。

通信总线

通信总线是跨硬件的,计算机系统之外的传送信息的总线,也叫外部总线。

时序控制划分:同步总线异步总线
数据传输划分:并行总线串行总线

系统总线的结构

单总线结构

CPU,主存,IO设备都挂在一组总线上,允许之间进行信息交换,无需经过中间设备干涉。
单总线并不只是一条总线。包括地址总线、数据总线、控制总线。

双总线结构

主存总线:用于在CPU、主存和通道之间传送数据
IO总线:一条用于IO设备,相当于低速总线
通道:就是高速处理IO的一个设备,主要在操作系统中详解。

三总线结构

主存总线、IO总线和DMA(直接内存访问)总线
注:DMA是内存交互高速外设数据

总线标准(记不住)

总线的性能指标

总线传输周期:执行一次总线操作所需的时间,包括若干总线时钟周期构成。
总线时钟周期:机器的时钟周期
总线工作频率:总线上各种操作的效率,总线周期的倒数
总线时钟频率:机器的时钟频率,时钟周期的倒数。
总线宽度:同时能够传送的数据位数,xx位总线
总线带宽:最大数据传输率,一秒传多少字节。计算公式:总线工作频率*(总线宽度/8)
总线复用:不同时间传不同信息,大部分都采用总线复用。
信号线数:地址总线,数据总线和控制总线线数之和。

注意:地址总线和数据总线的区别
地址总线是单向的,用于CPU向主存外设传输地址信息。
数据总线是双向的,CPU可用于输出数据和读取数据。
这里联想到CPU内部的MAR和MDR,MDR是双向的,但MAR只能是单向的,只有M[MAR]->MDR中。

数据总线多少根就是指多少位数据

// pages/stats/stats.js const eventBus = require('../../utils/event-bus.js'); Page({ data: { loading: true, dataType: 0, dataTypes: ['步数', '饮水', '睡眠'], years: ['2023', '2024', '2025'], months: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'], selectedYear: '2025', selectedMonth: '06', statsData: { average: 0, max: 0, completion: 0 }, chartData: { labels: [], values: [] }, // 添加重绘标志 needRedraw: false }, onLoad() { // 初始化事件总线 this.initEventBus(); // 设置默认日期为当前年月 const now = new Date(); this.setData({ selectedYear: now.getFullYear().toString(), selectedMonth: (now.getMonth() + 1).toString().padStart(2, '0') }, () => { this.loadStats(); }); }, // 初始化事件总线(关键修复) initEventBus() { this.dataUpdatedListener = () => { console.log('收到数据更新事件,重新加载统'); this.loadStats(); }; eventBus.on('healthDataUpdated', this.dataUpdatedListener); }, onUnload() { eventBus.off('healthDataUpdated', this.dataUpdatedListener); }, onShow() { // 页面显示时强制重绘 if (this.data.needRedraw) { this.setData({ needRedraw: false }, () => { setTimeout(() => this.drawChart(), 100); }); } }, // 加载统数据(关键修复) loadStats() { const app = getApp(); const records = app.getAllRecords(); const filteredRecords = this.filterRecordsByMonth(records); // 准备图表数据 const chartData = this.prepareChartData(filteredRecords); // 算统数据 const statsData = this.calculateStats(filteredRecords); this.setData({ statsData, chartData, loading: false, needRedraw: true // 设置重绘标志 }, () => { // 等待视图更新后绘制 setTimeout(() => { this.drawChart(); }, 300); }); }, // 修复日期筛选逻辑 filterRecordsByMonth(records) { const { selectedYear, selectedMonth } = this.data; return records.filter(record => { const [year, month] = record.date.split('-'); const normalizedMonth = month.padStart(2, '0'); return year === selectedYear && normalizedMonth === selectedMonth; }).sort((a, b) => new Date(a.date) - new Date(b.date)); }, // 准备图表数据 prepareChartData(records) { const labels = []; const values = []; records.forEach(record => { const day = record.date.split('-')[2]; labels.push(`${parseInt(day)}`); // 直接映射类型字段 const typeMap = { 0: 'steps', 1: 'water', 2: 'sleep' }; const typeKey = typeMap[this.data.dataType]; values.push(typeKey ? record[typeKey] || 0 : 0); }); return { labels, values }; }, // 算统数据 calculateStats(records) { if (!records || records.length === 0) { return { average: 0, max: 0, completion: 0 }; } // 直接映射类型字段 const typeMap = { 0: 'steps', 1: 'water', 2: 'sleep' }; const typeKey = typeMap[this.data.dataType]; const values = records.map(r => r[typeKey] || 0); const sum = values.reduce((acc, val) => acc + val, 0); const average = values.length > 0 ? (sum / values.length).toFixed(1) : 0; const max = Math.max(...values); const app = getApp(); const userInfo = app.globalData.userInfo; let target = 0; switch (this.data.dataType) { case 0: target = userInfo.target_steps || 10000; break; case 1: target = userInfo.target_water || 2.5; break; case 2: target = userInfo.target_sleep || 8; break; } let completion = 0; if (target > 0 && average > 0) { completion = (average / target) * 100; completion = Math.min(100, completion).toFixed(0); } return { average, max, completion }; }, // 切换数据类型 changeDataType(e) { this.setData({ dataType: e.detail.value }, () => { this.loadStats(); }); }, // 切换年份 changeYear(e) { this.setData({ selectedYear: this.data.years[e.detail.value] }, () => { this.loadStats(); }); }, // 切换月份 changeMonth(e) { this.setData({ selectedMonth: this.data.months[e.detail.value] }, () => { this.loadStats(); }); }, // 关键修复:确保Canvas正确销毁和重绘 drawChart() { // 销毁旧Canvas上下文 if (this.ctx) { try { this.ctx = null; } catch (e) { console.warn('Canvas上下文销毁异常', e); } } // 创建新Canvas上下文 this.ctx = wx.createCanvasContext('chartCanvas'); const { labels, values } = this.data.chartData; // 清除画布 this.ctx.clearRect(0, 0, 320, 200); this.ctx.draw(true); if (labels.length === 0) { console.log('无数据,跳过绘图'); return; } const canvasWidth = 320; const canvasHeight = 200; const paddingLeft = 45; const paddingTop = 25; const paddingRight = 25; const paddingBottom = 35; const chartWidth = canvasWidth - paddingLeft - paddingRight; const chartHeight = canvasHeight - paddingTop - paddingBottom; // 绘制坐标轴 this.ctx.beginPath(); this.ctx.moveTo(paddingLeft, paddingTop); this.ctx.lineTo(paddingLeft, paddingTop + chartHeight); this.ctx.lineTo(paddingLeft + chartWidth, paddingTop + chartHeight); this.ctx.strokeStyle = '#ddd'; this.ctx.stroke(); // 确定最大值 let maxValue = Math.max(...values, 1); // 确保最小值至少为1 // 根据数据类型调整最大值 if (this.data.dataType === 0) maxValue = Math.max(maxValue, 50000); else if (this.data.dataType === 1) maxValue = Math.max(maxValue, 5); else if (this.data.dataType === 2) maxValue = Math.max(maxValue, 12); // 绘制数据点和折线 const pointRadius = 4; const dataPoints = []; for (let i = 0; i < values.length; i++) { const x = paddingLeft + (i / (labels.length - 1)) * chartWidth; const y = paddingTop + chartHeight - (values[i] / maxValue) * chartHeight; dataPoints.push({ x, y }); this.ctx.beginPath(); this.ctx.arc(x, y, pointRadius, 0, Math.PI * 2); this.ctx.fillStyle = '#2c9cf1'; this.ctx.fill(); this.ctx.font = '10px sans-serif'; this.ctx.fillStyle = '#666'; this.ctx.textAlign = 'center'; this.ctx.fillText(labels[i], x, paddingTop + chartHeight + 15); } // 绘制折线 this.ctx.beginPath(); this.ctx.moveTo(dataPoints[0].x, dataPoints[0].y); for (let i = 1; i < dataPoints.length; i++) { this.ctx.lineTo(dataPoints[i].x, dataPoints[i].y); } this.ctx.strokeStyle = '#2c9cf1'; this.ctx.lineWidth = 2; this.ctx.stroke(); // 绘制值标签 for (let i = 0; i < values.length; i++) { let displayValue; switch (this.data.dataType) { case 0: displayValue = `${values[i]}步`; break; case 1: displayValue = `${values[i]}L`; break; case 2: displayValue = `${values[i]}小时`; break; default: displayValue = values[i].toString(); } this.ctx.font = '10px sans-serif'; this.ctx.fillStyle = '#2c9cf1'; this.ctx.textAlign = 'center'; this.ctx.fillText(displayValue, dataPoints[i].x, dataPoints[i].y - 10); } // 绘制Y轴刻度 this.ctx.font = '10px sans-serif'; this.ctx.fillStyle = '#666'; this.ctx.textAlign = 'right'; this.ctx.textBaseline = 'middle'; for (let i = 0; i <= 3; i++) { const value = (maxValue * (3 - i) / 3).toFixed(1); const y = paddingTop + (chartHeight * i) / 3; this.ctx.beginPath(); this.ctx.moveTo(paddingLeft - 5, y); this.ctx.lineTo(paddingLeft, y); this.ctx.strokeStyle = '#ddd'; this.ctx.stroke(); this.ctx.fillText(value, paddingLeft - 8, y); } // 确保绘制完成 this.ctx.draw(true); } }); 页面中完成率不管数值多少默认显示100,太离谱了,然后切换一下页面完成率就一直是0了,让完成率的算变正常,可以用取巧的方法
06-14
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值